blob: c33d330c49fb6397d77141190221576486086af7 [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">
<simple-method method-name="getNextInvoiceId" short-description="Get Next invoiceId">
<!-- try to find PartyAcctgPreference for parameters.partyId, see if we need any special invoice number sequencing -->
<entity-one entity-name="PartyAcctgPreference" value-field="partyAcctgPreference" auto-field-map="false">
<field-map field-name="partyId" from-field="parameters.partyId"/>
</entity-one>
<log level="info" message="In getNextInvoiceId partyId is [${parameters.partyId}], partyAcctgPreference: ${partyAcctgPreference}"/>
<if-not-empty field="partyAcctgPreference">
<get-related-one relation-name="InvoiceCustomMethod" value-field="partyAcctgPreference" to-value-field="customMethod"/>
<else>
<log level="warning" message="Acctg preference not defined for partyId [${parameters.partyId}]"/>
</else>
</if-not-empty>
<if-not-empty field="customMethod">
<set field="customMethodName" from-field="customMethod.customMethodName"/>
<else><!-- retreive service from deprecated enumeration -->
<if-compare operator="equals" value="INVSQ_ENF_SEQ" field="partyAcctgPreference.oldInvoiceSequenceEnumId">
<set field="customMethodName" value="invoiceSequenceEnforced"/>
</if-compare>
<if-compare operator="equals" value="INVSQ_RESTARTYR" field="partyAcctgPreference.oldInvoiceSequenceEnumId">
<set field="customMethodName" value="invoiceSequenceRestart"/>
</if-compare>
</else>
</if-not-empty>
<if-not-empty field="customMethodName">
<set-service-fields service-name="${customMethodName}" map="parameters" to-map="customMethodMap"/>
<set field="customMethodMap.partyAcctgPreference" from-field="partyAcctgPreference"/>
<call-service service-name="${customMethodName}" in-map-name="customMethodMap">
<result-to-field result-name="invoiceId" field="invoiceIdTemp"/>
</call-service>
<else>
<log level="info" message="In createInvoice sequence enum Standard"/>
<!-- default to the default sequencing: INVSQ_STANDARD -->
<set from-field="parameters.invoiceId" field="invoiceIdTemp"/>
<if-empty field="invoiceIdTemp">
<sequenced-id sequence-name="Invoice" field="invoiceIdTemp"/>
<else>
<!-- check the provided ID -->
<check-id field="invoiceIdTemp"/>
<check-errors/>
</else>
</if-empty>
</else>
</if-not-empty>
<!-- use invoiceIdTemp along with the invoiceIdPrefix to create the real ID -->
<set field="invoiceId" value="${partyAcctgPreference.invoiceIdPrefix}${str:toString(invoiceIdTemp)}"/>
<field-to-result field="invoiceId" result-name="invoiceId"/>
</simple-method>
<simple-method method-name="invoiceSequenceEnforced" short-description="Enforced Sequence (no gaps, per organization)">
<log level="info" message="In createInvoice sequence enum Enforced"/>
<set field="partyAcctgPreference" from-field="parameters.partyAcctgPreference"/>
<!-- this is sequential sequencing, we can't skip a number, also it must be a unique sequence per partyIdFrom -->
<if-not-empty field="partyAcctgPreference.lastInvoiceNumber">
<calculate field="partyAcctgPreference.lastInvoiceNumber" type="Long">
<calcop operator="add" field="partyAcctgPreference.lastInvoiceNumber"/>
<number value="1"/>
</calculate>
<else>
<calculate field="partyAcctgPreference.lastInvoiceNumber" type="Long"><number value="1"/></calculate>
</else>
</if-not-empty>
<store-value value-field="partyAcctgPreference"/>
<set from-field="partyAcctgPreference.lastInvoiceNumber" field="invoiceId"/>
<field-to-result field="invoiceId" result-name="invoiceId"/>
</simple-method>
<simple-method method-name="invoiceSequenceRestart" short-description="Restart on Fiscal Year (no gaps, per org, reset to 1 each year)">
<log level="info" message="In createInvoice sequence enum Restart"/>
<set field="partyAcctgPreference" from-field="parameters.partyAcctgPreference"/>
<!-- this is sequential sequencing, we can't skip a number; except that it is restarted each fiscal year -->
<now-timestamp field="nowTimestamp"/>
<if-empty field="partyAcctgPreference.lastInvoiceRestartDate">
<!-- if no lastInvoiceRestartDate then it's easy, just start now with 1 -->
<calculate field="partyAcctgPreference.lastInvoiceNumber" type="Long"><number value="1"/></calculate>
<set from-field="nowTimestamp" field="partyAcctgPreference.lastInvoiceRestartDate"/>
<else>
<!-- first figure out if we need to reset the lastInvoiceNumber; is the lastInvoiceRestartDate after the fiscalYearStartMonth/Day for this year? -->
<calculate field="zeroLong" type="Long"><number value="0"/></calculate>
<call-class-method class-name="org.ofbiz.base.util.UtilDateTime" method-name="getYearStart" ret-field="curYearFiscalStartDate">
<field field="nowTimestamp" type="java.sql.Timestamp"/>
<field field="partyAcctgPreference.fiscalYearStartDay" type="java.lang.Number"/>
<field field="partyAcctgPreference.fiscalYearStartMonth" type="java.lang.Number"/>
<field field="zeroLong" type="java.lang.Number"/>
</call-class-method>
<if>
<condition>
<and>
<if-compare-field field="partyAcctgPreference.lastInvoiceRestartDate" to-field="curYearFiscalStartDate" operator="less" type="Timestamp"/>
<if-compare-field field="nowTimestamp" to-field="curYearFiscalStartDate" operator="greater-equals" type="Timestamp"/>
</and>
</condition>
<then>
<!-- less than fiscal year start, we need to reset it -->
<calculate field="partyAcctgPreference.lastInvoiceNumber" type="Long"><number value="1"/></calculate>
<set from-field="nowTimestamp" field="partyAcctgPreference.lastInvoiceRestartDate"/>
</then>
<else>
<!-- greater than or equal to fiscal year start or nowTimestamp hasn't yet hit the current year fiscal start date, we're okay, just increment -->
<calculate field="partyAcctgPreference.lastInvoiceNumber" type="Long">
<calcop operator="add" field="partyAcctgPreference.lastInvoiceNumber"/>
<number value="1"/>
</calculate>
</else>
</if>
</else>
</if-empty>
<store-value value-field="partyAcctgPreference"/>
<!-- get the current year string for prefix, etc; simple 4 digit year date string (using system defaults) -->
<set field="curYearString" value="${str:toString(date:year(partyAcctgPreference.lastInvoiceRestartDate, util:defaultTimeZone(), util:defaultLocale()))}"/>
<set field="invoiceId" value="${curYearString}-${str:toString(partyAcctgPreference.lastInvoiceNumber)}"/>
<field-to-result field="invoiceId" result-name="invoiceId"/>
</simple-method>
<simple-method method-name="createInvoice" short-description="Create a new Invoice">
<now-timestamp field="nowTimestamp"/>
<make-value value-field="newEntity" entity-name="Invoice"/>
<!-- call getNextInvoiceId service with the parameters.partyIdFrom when invoice Id is not suplied
else use it from the input -->
<if-empty field="parameters.invoiceId">
<set-service-fields service-name="getNextInvoiceId" to-map="getNextInvoiceIdMap" map="parameters"/>
<set field="getNextInvoiceIdMap.partyId" from-field="parameters.partyIdFrom"/>
<call-service service-name="getNextInvoiceId" in-map-name="getNextInvoiceIdMap">
<result-to-field result-name="invoiceId" field="parameters.invoiceId"/>
</call-service>
</if-empty>
<field-to-result field="parameters.invoiceId" result-name="invoiceId"/>
<!-- set the invoice date if not provided -->
<if-empty field="parameters.invoiceDate">
<set from-field="nowTimestamp" field="parameters.invoiceDate"/>
</if-empty>
<!-- set the invoice status if not provided -->
<if-empty field="parameters.statusId">
<set field="parameters.statusId" value="INVOICE_IN_PROCESS"/>
</if-empty>
<!-- use currency of receiving company -->
<entity-one entity-name="Party" value-field="party"/>
<if-not-empty field="party.preferredCurrencyUomId">
<set field="parameters.currencyUomId" from-field="party.preferredCurrencyUomId"/>
</if-not-empty>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<create-value value-field="newEntity"/>
<!-- create new status entry, and set lastStatusUpdate date -->
<make-value value-field="newInvoiceStatus" entity-name="InvoiceStatus"/>
<set from-field="newEntity.invoiceId" field="newInvoiceStatus.invoiceId"/>
<set from-field="newEntity.statusId" field="newInvoiceStatus.statusId"/>
<set from-field="nowTimestamp" field="newInvoiceStatus.statusDate"/>
<create-value value-field="newInvoiceStatus"/>
</simple-method>
<simple-method method-name="copyInvoice" short-description="Create a new Invoice from an existing invoice">
<set field="invoiceLookup.invoiceId" from-field="parameters.invoiceIdToCopyFrom"/>
<call-service service-name="getInvoice" in-map-name="invoiceLookup">
<result-to-field result-name="invoice" field="invoice"/>
<result-to-field result-name="invoiceItems" field="invoiceItems"/>
</call-service>
<set field="invoice.invoiceId" from-field="parameters.invoiceId"/>
<now-timestamp field="nowTimestamp"/>
<set field="invoice.invoiceDate" from-field="nowTimestamp"/>
<set field="invoice.statusId" value="INVOICE_IN_PROCESS"/>
<if-not-empty field="parameters.invoiceTypeId">
<set field="invoice.invoiceTypeId" from-field="parameters.invoiceTypeId"/>
</if-not-empty>
<set-service-fields service-name="createInvoice" map="invoice" to-map="newInvoice"/>
<clear-field field="newInvoice.invoiceId"/>
<call-service service-name="createInvoice" in-map-name="newInvoice">
<result-to-field result-name="invoiceId" field="invoiceId"/>
</call-service>
<field-to-result field="invoiceId" result-name="invoiceId"/>
<field-to-request field="invoiceId" request-name="invoiceId"/>
<iterate entry="invoiceItem" list="invoiceItems">
<set-service-fields service-name="createInvoiceItem" map="invoiceItem" to-map="createInvoiceItem"/>
<set field="createInvoiceItem.invoiceId" from-field="invoiceId"/>
<call-service service-name="createInvoiceItem" in-map-name="createInvoiceItem"/>
</iterate>
</simple-method>
<simple-method method-name="getInvoice" short-description="Retrieve an invoice and the items">
<!-- find the invoice record -->
<make-value value-field="lookupPKMap" entity-name="Invoice"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="Invoice" map="lookupPKMap" value-field="invoiceValue"/>
<field-to-result field="invoiceValue" result-name="invoice"/>
<!-- and the items -->
<get-related value-field="invoiceValue" relation-name="InvoiceItem" list="invoiceItemValues"/>
<field-to-result field="invoiceItemValues" result-name="invoiceItems"/>
</simple-method>
<simple-method method-name="updateInvoice" short-description="Update the header of an existing Invoice">
<call-simple-method method-name="InvoiceStatusInProgress"/>
<!-- find the current record -->
<make-value value-field="lookupPKMap" entity-name="Invoice"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="Invoice" map="lookupPKMap" value-field="lookedUpValue"/>
<!-- only try to update content if the status is in process.... -->
<if-compare field="lookedUpValue.statusId" operator="equals" value="INVOICE_IN_PROCESS">
<clone-value value-field="lookedUpValue" new-value-field="savedValue"/>
<set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
<!-- only save if something has changed, do not update status here -->
<set from-field="savedValue.statusId" field="lookedUpValue.statusId"/> <!-- get old status back -->
<if-compare-field field="lookedUpValue" to-field="savedValue" operator="not-equals" type="Object">
<store-value value-field="lookedUpValue"/> <!-- update all non status and key fields -->
</if-compare-field>
<else>
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceUpdateOnlyWithInProcessStatus"/>
</add-error>
<log level="error" message="Can only update Invoice, when status is in-process...current Status: ${lookedUpValue.statusId}"/>
<check-errors/>
</else>
</if-compare>
<!-- check if there is a requested status change if yes call invoice status update service -->
<if-not-empty field="parameters.statusId">
<if-compare-field field="parameters.statusId" to-field="savedValue.statusId" operator="not-equals">
<set from-field="parameters.invoiceId" field="inputMap.invoiceId"/>
<set from-field="parameters.statusId" field="inputMap.statusId"/>
<now-timestamp field="inputMap.statusDate"/>
<call-service service-name="setInvoiceStatus" in-map-name="inputMap"/>
</if-compare-field>
</if-not-empty>
</simple-method>
<simple-method method-name="sendInvoicePerEmail" short-description="Send an invoice per Email">
<set-service-fields service-name="sendMailFromScreen" map="parameters" to-map="emailParams"/>
<set field="emailParams.xslfoAttachScreenLocation" value="component://accounting/widget/AccountingPrintScreens.xml#InvoicePDF"/>
<set field="emailParams.bodyParameters.invoiceId" from-field="parameters.invoiceId"/>
<set field="emailParams.bodyParameters.userLogin" from-field="parameters.userLogin"/>
<set field="emailParams.bodyParameters.other" from-field="parameters.other"/><!-- to to print in 'other currency' -->
<call-service-asynch service-name="sendMailFromScreen" in-map-name="emailParams"/>
<property-to-field resource="AccountingUiLabels" property="AccountingEmailScheduledToSend" field="successMessage"/>
</simple-method>
<simple-method method-name="createInvoiceItem" short-description="Create a new Invoice Item">
<set field="invoiceId" from-field="parameters.invoiceId"/>
<call-simple-method method-name="InvoiceStatusInProgress"/>
<make-value value-field="newEntity" entity-name="InvoiceItem"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.invoiceItemSeqId">
<make-next-seq-id value-field="newEntity" seq-field-name="invoiceItemSeqId"/> <!-- this finds the next sub-sequence ID -->
<field-to-result field="newEntity.invoiceItemSeqId" result-name="invoiceItemSeqId"/>
</if-empty>
<!-- if there is no amount and a productItem is supplied fill the amount(price) and description from the product record
TODO: there are return adjustments now that make this code very broken. The check for price was added as a quick fix. -->
<if-empty field="parameters.amount">
<if-not-empty field="parameters.productId">
<entity-one entity-name="Product" value-field="product"/>
<set from-field="product.description" field="newEntity.description"/>
<set from-field="product" field="calculateProductPriceMap.product"/>
<call-service service-name="calculateProductPrice" in-map-name="calculateProductPriceMap">
<result-to-field result-name="price" field="newEntity.amount"/>
</call-service>
</if-not-empty>
</if-empty>
<if-not-empty field="parameters.productId">
<if-empty field="parameters.quantity">
<set field="newEntity.quantity" value="1.0" type="BigDecimal"/>
</if-empty>
</if-not-empty>
<if-empty field="newEntity.amount">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceAmountIsMandatory"/>
</add-error>
</if-empty>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="updateInvoiceItem"
short-description="Update an existing Invoice Item">
<call-simple-method method-name="InvoiceStatusInProgress"/>
<make-value value-field="lookupPKMap" entity-name="InvoiceItem"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="InvoiceItem" map="lookupPKMap" value-field="lookedUpValue"/>
<clone-value value-field="lookedUpValue" new-value-field="savedValue"/>
<!-- set all parameters -->
<set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
<!-- check if the productNumber is updated, when yes retrieve product description and price -->
<if-not-empty field="productId">
<if-compare-field to-field="lookedUpValue.productId" field="savedValue.productId" operator="not-equals">
<entity-one entity-name="Product" value-field="product"/>
<set from-field="product.description" field="lookedUpValue.description"/>
<set from-field="product" field="calculateProductPriceMap.product"/>
<call-service service-name="calculateProductPrice" in-map-name="calculateProductPriceMap">
<result-to-field result-name="price" field="lookedUpValue.amount"/>
</call-service>
</if-compare-field>
</if-not-empty>
<if-empty field="newEntity.amount">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceAmountIsMandatory"/>
</add-error>
</if-empty>
<if-compare-field field="lookedUpValue" to-field="savedValue" operator="not-equals" type="Object">
<store-value value-field="lookedUpValue"/>
</if-compare-field>
<field-to-result field="lookedUpValue.invoiceItemSeqId" result-name="invoiceItemSeqId"/>
<field-to-result field="lookedUpValue.invoiceId" result-name="invoiceId"/>
</simple-method>
<simple-method method-name="removeInvoiceItem" short-description="Remove an existing Invoice Item">
<call-simple-method method-name="InvoiceStatusInProgress"/>
<set field="invoiceId" from-field="parameters.invoiceId"/>
<call-simple-method method-name="InvoiceStatusInProgress"/>
<set field="paymentApplicationMap.invoiceId" from-field="parameters.invoiceId"/>
<set field="paymentApplicationMap.invoiceItemSeqId" from-field="parameters.invoiceItemSeqId"/>
<if-not-empty field="parameters.invoiceItemSeqId">
<!-- check if there are specific item paymentApplications when yes remove those -->
<remove-by-and entity-name="PaymentApplication" map="paymentApplicationMap"/>
<else><!-- update global application with a null sequence number -->
<!-- TODO: reduce amount on global paymentApplication record -->
</else>
</if-not-empty>
<entity-one entity-name="InvoiceItem" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<simple-method method-name="removePaymentApplication" short-description="Remove an existing payment application">
<entity-one entity-name="PaymentApplication" value-field="paymentApplication">
<field-map field-name="paymentApplicationId" value="${parameters.paymentApplicationId}"/>
</entity-one>
<if-empty field="paymentApplication">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingPaymentApplicationNotFound"/>
</add-error>
<check-errors/>
</if-empty>
<!-- payment -->
<set field="currencyUomId" value=""/><!-- currency of the paymentApplication -->
<if-not-empty field="paymentApplication.paymentId">
<entity-one entity-name="Payment" value-field="payment">
<field-map field-name="paymentId" value="${paymentApplication.paymentId}"/>
</entity-one>
<if-not-empty field="payment">
<if-compare field="payment.statusId" operator="equals" value="PMNT_CONFIRMED">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingPaymentApplicationCannotRemovedWithConfirmedStatus"/>
</add-error>
</if-compare>
<check-errors/>
</if-not-empty>
<field-to-result field="paymentApplication.paymentId" result-name="paymentId"/>
<set field="currencyUomId" from-field="paymentId.currencyUomId"/>
</if-not-empty>
<!-- check invoice -->
<if-not-empty field="paymentApplication.invoiceId">
<entity-one entity-name="Invoice" value-field="invoice">
<field-map field-name="invoiceId" value="${paymentApplication.invoiceId}"/>
</entity-one>
<if-empty field="invoice">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceNotFound"/>
</add-error>
<log level="info" message="Invoice not found, invoice Id: ${invoiceId}"/>
<check-errors/>
</if-empty>
<set field="currencyUomId" from-field="invoice.currencyUomId"/>
<!-- if the invoice is already PAID, then set it back to READY and clear out the paidDate -->
<if-compare field="invoice.statusId" operator="equals" value="INVOICE_PAID">
<set field="invoiceStatusMap.invoiceId" value="${paymentApplication.invoiceId}"/>
<set field="invoiceStatusMap.statusId" value="INVOICE_READY"/>
<now-timestamp field="nowTimestamp"/>
<set field="invoiceStatusMap.statusDate" from-field="nowTimestamp"/>
<call-service service-name="setInvoiceStatus" in-map-name="invoiceStatusMap"/>
</if-compare>
<check-errors/>
<field-to-result field="paymentApplication.invoiceId" result-name="invoiceId"/>
<property-to-field resource="AccountingUiLabels" property="AccountingPaymentApplToInvoice" field="toMessage"/>
</if-not-empty>
<!-- invoice item -->
<if-not-empty field="paymentApplication.invoiceItemSeqId">
<field-to-result field="paymentApplication.invoiceItemSeqId" result-name="invoiceItemSeqId"/>
<property-to-field resource="AccountingUiLabels" property="AccountingApplicationToInvoiceItem" field="toMessage"/>
</if-not-empty>
<!-- toPayment -->
<if-not-empty field="paymentApplication.toPaymentId">
<entity-one entity-name="Payment" value-field="toPayment">
<field-map field-name="paymentId" value="${paymentApplication.toPaymentId}"/>
</entity-one>
<if-not-empty field="toPayment">
<if-compare field="toPayment.statusId" operator="equals" value="PMNT_CONFIRMED">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingPaymentApplicationCannotRemovedWithConfirmedStatus"/>
</add-error>
</if-compare>
<check-errors/>
</if-not-empty>
<property-to-field resource="AccountingUiLabels" property="AccountingPaymentApplToPayment" field="toMessage"/>
<field-to-result field="paymentApplication.toPaymentId" result-name="toPaymentId"/>
</if-not-empty>
<!-- billing account -->
<if-not-empty field="paymentApplication.billingAccountId">
<field-to-result field="paymentApplication.billingAccountId" result-name="billingAccountId"/>
<property-to-field resource="AccountingUiLabels" property="AccountingPaymentApplToBillingAccount" field="toMessage"/>
<entity-one entity-name="BillingAccount" value-field="billingAccount">
<field-map field-name="billingAccountId" from-field="paymentApplication.billingAccountId"/>
</entity-one>
<set field="currencyUomId" from-field="billingAccount.accountCurrencyUomId"/>
</if-not-empty>
<!-- tax authority -->
<if-not-empty field="paymentApplication.taxAuthGeoId">
<field-to-result field="paymentApplication.taxAuthGeoId" result-name="taxAuthGeoId"/>
<property-to-field resource="AccountingUiLabels" property="AccountingPaymentApplToTaxAuth" field="toMessage"/>
</if-not-empty>
<!-- finally delete application -->
<property-to-field resource="AccountingUiLabels" property="AccountingPaymentApplRemoved" field="successMessage"/>
<string-append field="successMessage" string=" ${toMessage}"/>
<remove-value value-field="paymentApplication"/>
</simple-method>
<simple-method method-name="createInvoiceRole" short-description="Create a Invoice Role">
<call-simple-method method-name="InvoiceStatusInProgress"/>
<make-value value-field="newEntity" entity-name="InvoiceRole"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.datetimePerformed"><now-timestamp field="newEntity.datetimePerformed"/></if-empty>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="removeInvoiceRole" short-description="Remove existing Invoice Role">
<call-simple-method method-name="InvoiceStatusInProgress"/>
<entity-one entity-name="InvoiceRole" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<simple-method method-name="setInvoiceStatus" short-description="Set The Invoice Status">
<entity-one entity-name="Invoice" value-field="invoice"/>
<field-to-result field="invoice.statusId" result-name="oldStatusId"/>
<field-to-result field="invoice.invoiceTypeId" result-name="invoiceTypeId"/>
<if-compare-field field="invoice.statusId" to-field="parameters.statusId" operator="not-equals">
<entity-one entity-name="StatusValidChange" value-field="statusChange" auto-field-map="false">
<field-map field-name="statusId" from-field="invoice.statusId"/>
<field-map field-name="statusIdTo" from-field="parameters.statusId"/>
</entity-one>
<if-empty field="statusChange">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingPSInvalidStatusChange"/>
</add-error>
<log level="error" message="Cannot change from ${invoice.statusId} to ${parameters.statusId}"/>
<check-errors/>
<else>
<!-- if new status is paid check if the complete invoice is applied. -->
<if-compare field="parameters.statusId" operator="equals" value="INVOICE_PAID">
<set field="notApplied" type="BigDecimal" value="${groovy:org.ofbiz.accounting.invoice.InvoiceWorker.getInvoiceNotApplied(invoice)}"/>
<if-compare field="notApplied" operator="not-equals" value="0.00" type="BigDecimal">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceCannotChangeStatusToPaid"/>
</add-error>
<check-errors/>
</if-compare>
<!-- if it's OK to mark invoice paid, use parameter for paidDate -->
<if-empty field="parameters.paidDate">
<now-timestamp field="nowTimestamp"/>
<set from-field="nowTimestamp" field="invoice.paidDate"/>
<else>
<set from-field="parameters.paidDate" field="invoice.paidDate"/>
</else>
</if-empty>
</if-compare>
<if-not-empty field="invoice.paidDate">
<if-compare field="parameters.statusId" operator="equals" value="INVOICE_READY">
<clear-field field="invoice.paidDate"/>
</if-compare>
</if-not-empty>
<set from-field="parameters.statusId" field="invoice.statusId"/>
<store-value value-field="invoice"/>
<make-value value-field="newEntity" entity-name="InvoiceStatus"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.statusDate">
<now-timestamp field="newEntity.statusDate"/>
</if-empty>
<create-value value-field="newEntity"/>
<!-- if the invoice is a payrol invoice, create the payment in the not-paid status -->
<if-compare field="invoice.invoiceTypeId" operator="equals" value="PAYROL_INVOICE">
<if>
<condition>
<or>
<if-compare field="parameters.statusId" operator="equals" value="INVOICE_APPROVED"/>
<if-compare field="parameters.statusId" operator="equals" value="INVOICE_READY"/>
</or>
</condition>
<then>
<!-- only generate payment if no application exist yet -->
<entity-and entity-name="PaymentApplication" list="paymentApplications">
<field-map field-name="invoiceId" from-field="parameters.invoiceId"/>
</entity-and>
<if-empty field="paymentApplications">
<set field="newp.partyIdFrom" from-field="invoice.partyId"/>
<set field="newp.partyIdTo" from-field="invoice.partyIdFrom"/>
<set field="newp.paymentMethodTypeId" value="COMPANY_CHECK"/>
<set field="newp.paymentTypeId" value="PAYROL_PAYMENT"/>
<set field="newp.statusId" value="PMNT_NOT_PAID"/>
<set field="newp.currencyUomId" from-field="invoice.currencyUomId"/>
<call-class-method class-name="org.ofbiz.accounting.invoice.InvoiceWorker" method-name="getInvoiceTotal" ret-field="newp.amount">
<field field="invoice" type="GenericValue"/>
</call-class-method>
<call-service service-name="createPayment" in-map-name="newp">
<result-to-field result-name="paymentId" field="payment.paymentId"/>
</call-service>
<set field="payAppl.invoiceId" from-field="invoice.invoiceId"/>
<set field="payAppl.paymentId" from-field="payment.paymentId"/>
<set field="payAppl.amountApplied" from-field="newp.amount"/>
<call-service service-name="createPaymentApplication" in-map-name="payAppl"/>
</if-empty>
</then>
</if>
</if-compare>
</else>
</if-empty>
</if-compare-field>
</simple-method>
<simple-method method-name="createInvoiceTerm" short-description="Create a Invoice Term">
<call-simple-method method-name="InvoiceStatusInProgress"/>
<make-value value-field="newEntity" entity-name="InvoiceTerm"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<sequenced-id sequence-name="InvoiceTerm" field="newEntity.invoiceTermId"/>
<field-to-result field="newEntity.invoiceTermId" result-name="invoiceTermId"/>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="copyInvoiceToTemplate" short-description="copy a invoice to a InvoiceType starting with 'template'">
<set field="parameters.invoiceIdToCopyFrom" from-field="parameters.invoiceId"/>
<if-compare field="parameters.invoiceTypeId" operator="equals" value="SALES_INVOICE">
<set field="parameters.invoiceTypeId" value="SALES_INV_TEMPLATE"/>
</if-compare>
<if-compare field="parameters.invoiceTypeId" operator="equals" value="PURCHASE_INVOICE">
<set field="parameters.invoiceTypeId" value="PUR_INV_TEMPLATE"/>
</if-compare>
<call-simple-method method-name="copyInvoice"/>
</simple-method>
<!-- ===============subroutine services =================-->
<simple-method method-name="InvoiceStatusInProgress" short-description="Check if the invoiceStatus is in progress">
<!-- find the current header record -->
<entity-one entity-name="Invoice" value-field="headerValue"/>
<if-empty field="headerValue">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceNotFound"/>
</add-error>
<log level="info" message="Invoice not found, invoice Id: ${invoiceId}"/>
<check-errors/>
</if-empty>
<!-- check if the status is in progress... -->
<if-compare field="headerValue.statusId" operator="not-equals" value="INVOICE_IN_PROCESS">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceUpdateOnlyWithInProcessStatus"/>
</add-error>
<log level="info" message="Can only update Invoice, when status is in-process...is now: ${headerValue.statusId}"/>
</if-compare>
<check-errors/>
</simple-method>
<simple-method method-name="createInvoiceContactMech" short-description="Create a ContactMech for an invoice">
<make-value value-field="invoiceContactMech" entity-name="InvoiceContactMech"/>
<set-pk-fields map="parameters" value-field="invoiceContactMech"/>
<create-value value-field="invoiceContactMech"/>
<field-to-result field="contactMechId" result-name="invoiceContactMech"/>
</simple-method>
<simple-method method-name="autoGenerateInvoiceFromExistingInvoice" short-description="Scheduled service to generate Invoice from an existing Invoice">
<entity-and entity-name="Invoice" list="invoices">
<field-map field-name="recurrenceInfoId" from-field="parameters.recurrenceInfoId"/>
</entity-and>
<iterate list="invoices" entry="invoice">
<set-service-fields service-name="copyInvoice" map="invoice" to-map="copyInvoiceCtx"/>
<set field="copyInvoiceCtx.invoiceIdToCopyFrom" from-field="invoice.invoiceId"/>
<call-service service-name="copyInvoice" in-map-name="copyInvoiceCtx">
<result-to-field result-name="invoiceId" field="invoiceId"/>
</call-service>
<set-service-fields service-name="updateInvoice" map="invoice" to-map="updateInvoiceCtx"/>
<set field="updateInvoiceCtx.invoiceId" from-field="invoiceId"/>
<if-compare field="updateInvoiceCtx.invoiceTypeId" operator="equals" value="SALES_INV_TEMPLATE">
<set field="updateInvoiceCtx.invoiceTypeId" value="SALES_INVOICE"/>
</if-compare>
<if-compare field="updateInvoiceCtx.invoiceTypeId" operator="equals" value="PUR_INV_TEMPLATE">
<set field="updateInvoiceCtx.invoiceTypeId" value="PURCHASE_INVOICE"/>
</if-compare>
<clear-field field="invoice"/>
<clear-field field="parameters.invoiceIdToCopyFrom"/>
<clear-field field="updateInvoiceCtx.recurrenceInfoId"/>
<call-service service-name="updateInvoice" in-map-name="updateInvoiceCtx"/>
</iterate>
</simple-method>
<simple-method method-name="cancelInvoice" short-description="Service to cancel the Invoices">
<entity-one entity-name="Invoice" value-field="invoice"/>
<if-empty field="invoice">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingInvoiceNotFound"/>
</add-error>
<check-errors/>
</if-empty>
<get-related relation-name="PaymentApplication" value-field="invoice" list="paymentApplications"/>
<iterate list="paymentApplications" entry="paymentApplication">
<get-related-one relation-name="Payment" value-field="paymentApplication" to-value-field="payment"/>
<if-compare field="payment.statusId" operator="equals" value="PMNT_CONFIRMED">
<set field="paymentStatusMap.paymentId" from-field="payment.paymentId"/>
<set field="isReceipt" value="${groovy:org.ofbiz.accounting.util.UtilAccounting.isReceipt(payment)}" type="Boolean"/>
<set field="isDisbursement" value="${groovy:org.ofbiz.accounting.util.UtilAccounting.isDisbursement(payment)}" type="Boolean"/>
<if-compare field="isReceipt" operator="equals" value="true" type="Boolean">
<set field="paymentStatusMap.statusId" value="PMNT_RECEIVED"/>
<else>
<if-compare field="isDisbursement" operator="equals" value="true" type="Boolean">
<set field="paymentStatusMap.statusId" value="PMNT_SENT"/>
</if-compare>
</else>
</if-compare>
<call-service service-name="setPaymentStatus" in-map-name="paymentStatusMap"/>
</if-compare>
<set field="removePaymentApplicationCtx.paymentApplicationId" from-field="paymentApplication.paymentApplicationId"/>
<call-service service-name="removePaymentApplication" in-map-name="removePaymentApplicationCtx"/>
</iterate>
<field-to-result result-name="invoiceTypeId" field="invoice.invoiceTypeId"/>
</simple-method>
<simple-method method-name="getInvoiceRunningTotal" short-description="calculate running total for Invoices">
<set field="invoiceIds" from-field="parameters.invoiceIds"/>
<set field="runningTotal" type="BigDecimal" value="0"/>
<entity-condition entity-name="Invoice" list="invoiceList">
<condition-expr field-name="invoiceId" operator="in" from-field="invoiceIds"/>
</entity-condition>
<iterate list="invoiceList" entry="invoice">
<set field="getInvoicePaymentInfoListCtx.invoiceId" from-field="invoice.invoiceId"/>
<call-service service-name="getInvoicePaymentInfoList" in-map-name="getInvoicePaymentInfoListCtx">
<result-to-field result-name="invoicePaymentInfoList"/>
</call-service>
<first-from-list list="invoicePaymentInfoList" entry="invoicePaymentInfo"/>
<set field="runningTotal" value="${runningTotal + invoicePaymentInfo.outstandingAmount}" type="BigDecimal"/>
</iterate>
<set-service-fields service-name="getPartyAccountingPreferences" map="parameters" to-map="getPartyAccountingPreferencesMap"/>
<call-service service-name="getPartyAccountingPreferences" in-map-name="getPartyAccountingPreferencesMap">
<result-to-field result-name="partyAccountingPreference"/>
</call-service>
<set field="currencyUomId" from-field="partyAccountingPreference.baseCurrencyUomId"/>
<if-empty field="currencyUomId">
<property-to-field resource="general" property="currency.uom.id.default" field="currencyUomId"/>
</if-empty>
<set field="invoiceRunningTotal" value="${groovy:org.ofbiz.base.util.UtilFormatOut.formatCurrency(runningTotal, currencyUomId, parameters.locale)}"/>
<field-to-result field="invoiceRunningTotal"/>
</simple-method>
<simple-method method-name="getInvoicesFilterByAssocType" short-description="Filter invoices by invoiceItemAssocTypeId">
<set field="invoiceList" from-field="parameters.invoiceList"/>
<set field="invoiceItemAssocTypeId" from-field="parameters.invoiceItemAssocTypeId"/>
<iterate list="invoiceList" entry="invoice">
<entity-and entity-name="InvoiceItemAssoc" list="invoiceItemAssocList" filter-by-date="true">
<field-map field-name="invoiceIdFrom" from-field="invoice.invoiceId"/>
<field-map field-name="invoiceItemAssocTypeId"/>
</entity-and>
<if-empty field="invoiceItemAssocList">
<field-to-list field="invoice" list="filteredInvoiceList"/>
</if-empty>
</iterate>
<field-to-result field="filteredInvoiceList"/>
</simple-method>
<simple-method method-name="removeInvoiceItemAssocOnCancelInvoice" short-description="Remove invoiceItemAssoc record on cancel invoice">
<entity-and entity-name="InvoiceItemAssoc" list="invoiceItemAssocs">
<field-map field-name="invoiceIdTo" from-field="parameters.invoiceId"/>
</entity-and>
<iterate entry="invoiceItemAssoc" list="invoiceItemAssocs">
<set-service-fields service-name="deleteInvoiceItemAssoc" map="invoiceItemAssoc" to-map="deleteInvoiceItemAssocMap"/>
<call-service service-name="deleteInvoiceItemAssoc" in-map-name="deleteInvoiceItemAssocMap"/>
<log level="info" message="Removed invoiceItemAssoc: ${invoiceItemAssoc}"/>
</iterate>
</simple-method>
<simple-method method-name="resetOrderItemBillingAndOrderAdjustmentBillingOnCancelInvoice"
short-description="Reset OrderItemBilling and OrderAdjustmentBilling records on cancel invoice, so it is isn't considered invoiced any more by createInvoiceForOrder service">
<entity-and entity-name="OrderItemBilling" list="orderItemBillings">
<field-map field-name="invoiceId" from-field="parameters.invoiceId"/>
</entity-and>
<iterate entry="orderItemBilling" list="orderItemBillings">
<set field="orderItemBilling.quantity" value="0" type="BigDecimal"/>
<store-value value-field="orderItemBilling"/>
</iterate>
<entity-and entity-name="OrderAdjustmentBilling" list="orderAdjustmentBillings">
<field-map field-name="invoiceId" from-field="parameters.invoiceId"/>
</entity-and>
<iterate entry="orderAdjustmentBilling" list="orderAdjustmentBillings">
<set field="orderAdjustmentBilling.amount" value="0" type="BigDecimal"/>
<store-value value-field="orderAdjustmentBilling"/>
</iterate>
</simple-method>
<simple-method method-name="massChangeInvoiceStatus" short-description="Service set status of Invoices in bulk.">
<iterate list="parameters.invoiceIds" entry="invoiceId">
<set field="setInvoiceStatusMap.invoiceId" from-field="invoiceId"/>
<set field="setInvoiceStatusMap.statusId" from-field="parameters.statusId"/>
<call-service service-name="setInvoiceStatus" in-map-name="setInvoiceStatusMap"/>
<clear-field field="setInvoiceStatusMap"/>
</iterate>
</simple-method>
<simple-method method-name="addtax" short-description="Set Parameter And Call Tax Calculate Service">
<entity-one entity-name="Invoice" value-field="invoice">
<field-map field-name="invoiceId" from-field="parameters.invoiceId"/>
</entity-one>
<entity-and entity-name="InvoiceItem" list="invoiceItems">
<field-map field-name="invoiceId" from-field="invoice.invoiceId"/>
</entity-and>
<entity-and entity-name="PartyContactMechPurpose" list="contacts">
<field-map field-name="partyId" from-field="invoice.partyId"/>
<field-map field-name="contactMechPurposeTypeId" value="SHIPPING_LOCATION"/>
</entity-and>
<if-empty field="contacts">
<entity-and entity-name="PartyContactMechPurpose" list="contacts">
<field-map field-name="partyId" from-field="invoice.partyId"/>
<field-map field-name="contactMechPurposeTypeId" value="GENERAL_LOCATION"/>
</entity-and>
</if-empty>
<if-empty field="contacts">
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingTaxCannotCalculate"/>
</add-error>
</if-empty>
<first-from-list entry="contactMech" list="contacts"/>
<entity-one entity-name="PostalAddress" value-field="postalAddress">
<field-map field-name="contactMechId" from-field="contactMech.contactMechId"/>
</entity-one>
<if-compare field="invoice.invoiceTypeId" value="SALES_INVOICE" operator="equals">
<set field="addtaxMap.billToPartyId" from-field="invoice.partyId"/>
</if-compare>
<if-compare field="invoice.invoiceTypeId" value="PURCHASE_INVOICE" operator="equals">
<set field="addtaxMap.billToPartyId" from-field="invoice.partyIdFrom"/>
</if-compare>
<set field="addtaxMap.payToPartyId" from-field="invoice.partyIdFrom"/>
<iterate list="invoiceItems" entry="invoiceItem">
<entity-and entity-name="Product" list="product">
<field-map field-name="productId" from-field="invoiceItem.productId"/>
</entity-and>
<first-from-list entry="itemProduct" list="product"/>
<if-not-empty field="invoiceItem.productId">
<entity-and entity-name="InvoiceItem" list="findinvoiceItems">
<field-map field-name="invoiceId" from-field="invoice.invoiceId"/>
<field-map field-name="productId" from-field="invoiceItem.productId"/>
<field-map field-name="invoiceItemTypeId" value="ITM_PROMOTION_ADJ"/>
</entity-and>
<if-not-empty field="findinvoiceItems">
<calculate field="total" decimal-scale="${roundingDecimals}" rounding-mode="${roundingMode}" type="BigDecimal">
<calcop operator="multiply">
<calcop operator="get" field="invoiceItem.quantity"/>
<calcop operator="get" field="invoiceItem.amount"/>
</calcop>
</calculate>
<set field="totalAmount" from-field="total" type="BigDecimal"/>
<calculate field="totalAmount" decimal-scale="${roundingDecimals}" rounding-mode="${roundingMode}" type="BigDecimal">
<calcop operator="subtract">
<calcop operator="get" field="totalAmount"/>
<calcop operator="get" field="invoiceItem.amount"/>
</calcop>
</calculate>
<else>
<calculate field="total" decimal-scale="${roundingDecimals}" rounding-mode="${roundingMode}" type="BigDecimal">
<calcop operator="multiply">
<calcop operator="get" field="invoiceItem.quantity"/>
<calcop operator="get" field="invoiceItem.amount"/>
</calcop>
</calculate>
<set field="totalAmount" from-field="total" type="BigDecimal"/>
</else>
</if-not-empty>
<else>
<set field="totalAmount" value="0" type="BigDecimal"/>
</else>
</if-not-empty>
<set field="itemAmount" from-field="totalAmount" type="BigDecimal"/>
<set field="itemPrice" from-field="invoiceItem.amount" type="BigDecimal"/>
<set field="addtaxMap.itemProductList[]" from-field="itemProduct"/>
<set field="addtaxMap.itemAmountList[]" from-field="itemAmount" type="BigDecimal"/>
<set field="addtaxMap.itemPriceList[]" from-field="itemPrice" type="BigDecimal"/>
<set field="addtaxMap.itemQuantityList[]" from-field="invoiceItem.quantity" type="BigDecimal"/>
<set field="addtaxMap.itemShippingList[]" type="BigDecimal" value="0"/>
</iterate>
<set field="addtaxMap.orderShippingAmount" type="BigDecimal" value="0"/>
<set field="addtaxMap.orderPromotionsAmount" type="BigDecimal" value="0"/>
<set field="addtaxMap.shippingAddress" from-field="postalAddress"/>
<if>
<condition>
<not><if-empty field="addtaxMap.itemProductList"></if-empty></not>
</condition>
<then>
<call-service service-name="calcTax" in-map-name="addtaxMap">
<result-to-field result-name="itemAdjustments" field="itemAdjustments"/>
<result-to-field result-name="orderAdjustments" field="orderAdjustments"/>
</call-service>
<iterate list="invoiceItems" entry="findItem">
<if>
<condition>
<not><if-empty field="findItem.productId"></if-empty></not>
</condition>
<then>
<set field="invoiceItemSeqId" from-field="findItem.invoiceItemSeqId"/>
<set field="productId" from-field="findItem.productId"/>
<set field="itemMap.itemSeqIdList[]" from-field="invoiceItemSeqId"/>
<set field="itemMap.productList[]" from-field="productId"/>
</then>
</if>
</iterate>
<set field="countItemId" value="-1" type="Long"/>
<iterate list="itemAdjustments" entry="itemAdjustment">
<calculate field="countItemId">
<calcop operator="add" field="countItemId">
<number value="1"/>
</calcop>
</calculate>
<if-not-empty field="itemAdjustment">
<iterate list="itemAdjustment" entry="orderAdjustment">
<set field="createInvoiceItemContext.invoiceId" from-field="invoice.invoiceId"/>
<if-compare field="invoice.invoiceTypeId" value="PURCHASE_INVOICE" operator="equals">
<set field="createInvoiceItemContext.invoiceItemTypeId" value="PITM_SALES_TAX"/>
<else>
<set field="createInvoiceItemContext.invoiceItemTypeId" value="ITM_SALES_TAX"/>
</else>
</if-compare>
<set field="createInvoiceItemContext.overrideGlAccountId" from-field="orderAdjustment.overrideGlAccountId"/>
<set field="createInvoiceItemContext.productId" from-field="itemMap.productList[countItemId]"/>
<set field="createInvoiceItemContext.taxAuthPartyId" from-field="orderAdjustment.taxAuthPartyId"/>
<set field="createInvoiceItemContext.taxAuthGeoId" from-field="orderAdjustment.taxAuthGeoId"/>
<set field="createInvoiceItemContext.amount" from-field="orderAdjustment.amount" type="BigDecimal"/>
<set field="createInvoiceItemContext.quantity" value="1"/>
<set field="createInvoiceItemContext.parentInvoiceItemSeqId" from-field="itemMap.itemSeqIdList[countItemId]"/>
<set field="createInvoiceItemContext.taxAuthorityRateSeqId" from-field="orderAdjustment.taxAuthorityRateSeqId"/>
<set field="createInvoiceItemContext.description" from-field="orderAdjustment.comments"/>
<!--call createInvoiceItem service for every ItemAdjustment-->
<call-service service-name="createInvoiceItem" in-map-name="createInvoiceItemContext"></call-service>
</iterate>
</if-not-empty>
</iterate>
<iterate list="orderAdjustments" entry="Adjustment">
<if-not-empty field="Adjustment">
<set field="InvoiceItemContext.invoiceId" from-field="invoice.invoiceId"/>
<if-compare field="invoice.invoiceTypeId" value="PURCHASE_INVOICE" operator="equals">
<set field="InvoiceItemContext.invoiceItemTypeId" value="PITM_SALES_TAX"/>
<else>
<set field="InvoiceItemContext.invoiceItemTypeId" value="ITM_SALES_TAX"/>
</else>
</if-compare>
<set field="InvoiceItemContext.overrideGlAccountId" from-field="Adjustment.overrideGlAccountId"/>
<set field="InvoiceItemContext.taxAuthPartyId" from-field="Adjustment.taxAuthPartyId"/>
<set field="InvoiceItemContext.taxAuthGeoId" from-field="Adjustment.taxAuthGeoId"/>
<set field="InvoiceItemContext.amount" from-field="Adjustment.amount" type="BigDecimal"/>
<set field="InvoiceItemContext.quantity" value="1"/>
<set field="InvoiceItemContext.taxAuthorityRateSeqId" from-field="Adjustment.taxAuthorityRateSeqId"/>
<!-- call createInvoiceItem service for every orderAdjustment -->
<call-service service-name="createInvoiceItem" in-map-name="InvoiceItemContext"></call-service>
</if-not-empty>
</iterate>
</then>
<else>
<add-error>
<fail-property resource="AccountingUiLabels" property="AccountingTaxProductIdCannotCalculate"/>
</add-error>
<log level="error" message="Cannot call calcTax service, when don't have productId"/>
<check-errors/>
</else>
</if>
</simple-method>
<simple-method method-name="createInvoiceFromOrder" short-description="Create an invoice from existing order when invoicePerShipment is N">
<entity-one value-field="orderHeader" entity-name="OrderHeader">
<field-map field-name="orderId" from-field="parameters.orderId"/>
</entity-one>
<set field="invoicePerShipment" from-field="orderHeader.invoicePerShipment"/>
<if-empty field="invoicePerShipment">
<property-to-field resource="AccountingConfig" property="create.invoice.per.shipment" field="invoicePerShipment"/>
</if-empty>
<if-compare operator="equals" value="N" field="invoicePerShipment">
<entity-and list="orderItemBilling" entity-name="OrderItemBilling">
<field-map field-name="orderId" from-field="parameters.orderId"/>
</entity-and>
<if-empty field="orderItemBilling">
<set field="createInvoiceContext.orderId" from-field="parameters.orderId"/>
<call-service service-name="createInvoiceForOrderAllItems" in-map-name="createInvoiceContext">
<result-to-field result-name="invoiceId" field="invoiceId"/>
</call-service>
<else>
<entity-and list="orderItems" entity-name="OrderItem">
<field-map field-name="orderId" from-field="parameters.orderId"/>
<order-by field-name="orderItemSeqId"/>
</entity-and>
<iterate entry="orderItem" list="orderItems">
<entity-and list="checkOrderItem" entity-name="OrderItemBilling">
<field-map field-name="orderId" from-field="parameters.orderId"/>
<field-map field-name="orderItemSeqId" from-field="orderItem.orderItemSeqId"/>
</entity-and>
<if-empty field="checkOrderItem">
<field-to-list list="billItems" field="orderItem"/>
</if-empty>
<set field="createInvoiceContext.orderId" from-field="parameters.orderId"/>
<set field="createInvoiceContext.billItems" from-field="billItems"/>
</iterate>
<call-service service-name="createInvoiceForOrder" in-map-name="createInvoiceContext">
<result-to-field result-name="invoiceId" field="invoiceId"/>
</call-service>
</else>
</if-empty>
<field-to-result field="invoiceId" result-name="invoiceId"/>
</if-compare>
</simple-method>
<!-- InvoiceContent -->
<simple-method method-name="createInvoiceContent" short-description="Create Content For Invoice">
<make-value value-field="newEntity" entity-name="InvoiceContent"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="nowTimestamp"/>
<set field="newEntity.fromDate" from-field="nowTimestamp"/>
</if-empty>
<create-value value-field="newEntity"/>
<set-service-fields service-name="updateContent" map="parameters" to-map="updateContent"/>
<call-service service-name="updateContent" in-map-name="updateContent"/>
<field-to-result field="newEntity.contentId" result-name="contentId"/>
<field-to-result field="newEntity.invoiceId" result-name="invoiceId"/>
<field-to-result field="newEntity.invoiceContentTypeId" result-name="invoiceContentTypeId"/>
</simple-method>
<simple-method method-name="updateInvoiceContent" short-description="Update Content For Invoice">
<make-value value-field="lookupPKMap" entity-name="InvoiceContent"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/>
<set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
<store-value value-field="lookedUpValue"/>
<set-service-fields service-name="updateContent" map="parameters" to-map="updateContent"/>
<call-service service-name="updateContent" in-map-name="updateContent"/>
</simple-method>
<simple-method method-name="removeInvoiceContent" short-description="Remove Content From Invoice">
<make-value value-field="lookupPKMap" entity-name="InvoiceContent"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<simple-method method-name="createSimpleTextContentForInvoice" short-description="Create Simple Text Content For Invoice">
<set-service-fields service-name="createInvoiceContent" map="parameters" to-map="createInvoiceContentMap"/>
<set-service-fields service-name="createSimpleTextContent" map="parameters" to-map="createSimpleTextMap"/>
<call-service service-name="createSimpleTextContent" in-map-name="createSimpleTextMap">
<result-to-field result-name="contentId" field="createInvoiceContentMap.contentId"/>
</call-service>
<call-service service-name="createInvoiceContent" in-map-name="createInvoiceContentMap"/>
</simple-method>
<simple-method method-name="updateSimpleTextContentForInvoice" short-description="Update Simple Text Content For Invoice">
<set-service-fields service-name="updateInvoiceContent" map="parameters" to-map="updateInvoiceContent"/>
<call-service service-name="updateInvoiceContent" in-map-name="updateInvoiceContent"/>
<set-service-fields service-name="updateSimpleTextContent" map="parameters" to-map="updateSimpleText"/>
<call-service service-name="updateSimpleTextContent" in-map-name="updateSimpleText"/>
</simple-method>
<simple-method method-name="isInvoiceInForeignCurrency" short-description="check if a invoice is in a foreign currency related to the accounting company.">
<entity-one value-field="invoice" entity-name="InvoiceAndType">
<field-map field-name="invoiceId" from-field="parameters.invoiceId"/>
</entity-one>
<if-empty field="invoice">
<log level="error" message="Invoice not found"/>
<return/>
</if-empty>
<if-compare field="invoice.parentTypeId" operator="equals" value="PURCHASE_INVOICE">
<set field="pref.organizationPartyId" from-field="invoice.partyId"/>
</if-compare>
<if-compare field="invoice.parentTypeId" operator="equals" value="SALES_INVOICE">
<set field="pref.organizationPartyId" from-field="invoice.partyIdFrom"/>
</if-compare>
<call-service service-name="getPartyAccountingPreferences" in-map-name="pref">
<result-to-field result-name="partyAccountingPreference"/>
</call-service>
<if-compare-field to-field="partyAccountingPreference.baseCurrencyUomId" operator="equals" field="invoice.currencyUomId">
<set field="isForeign" value="false" type="Boolean"/>
<else>
<set field="isForeign" value="true" type="Boolean"/>
</else>
</if-compare-field>
<field-to-result field="isForeign"/>
</simple-method>
</simple-methods>