This is an automated email from the ASF dual-hosted git repository.

nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git

commit 7230aa804664cbeb1a70efdea3940b7e559fe72d
Author: Nicolas Malin <nicolas.ma...@nereide.fr>
AuthorDate: Wed Sep 15 17:34:58 2021 +0200

    Improved: Convert createMatchingPaymentApplication service from mini-lang 
to groovy DSL (OFBIZ-11500)
    
    Thanks to Rohit Koushal to submit the patch
---
 .../groovyScripts/payment/PaymentServices.groovy   | 117 ++++++++++++++++++
 .../minilang/payment/PaymentServices.xml           | 135 ---------------------
 .../accounting/servicedef/services_payment.xml     |   4 +-
 3 files changed, 119 insertions(+), 137 deletions(-)

diff --git 
a/applications/accounting/groovyScripts/payment/PaymentServices.groovy 
b/applications/accounting/groovyScripts/payment/PaymentServices.groovy
index fbc0edd..cfa29b8 100644
--- a/applications/accounting/groovyScripts/payment/PaymentServices.groovy
+++ b/applications/accounting/groovyScripts/payment/PaymentServices.groovy
@@ -26,6 +26,8 @@ import org.apache.ofbiz.entity.condition.EntityCondition
 import org.apache.ofbiz.entity.condition.EntityConditionBuilder
 import org.apache.ofbiz.entity.condition.EntityOperator
 import org.apache.ofbiz.entity.GenericValue
+import org.apache.ofbiz.entity.util.EntityTypeUtil
+import org.apache.ofbiz.entity.util.EntityUtilProperties
 import org.apache.ofbiz.service.ServiceUtil
 
 import java.sql.Timestamp
@@ -713,3 +715,118 @@ def setPaymentStatus() {
     payment.store()
     return success(oldStatusId: oldStatusId)
 }
+
+def createMatchingPaymentApplication() {
+    String autoCreate = EntityUtilProperties.getPropertyValue("accounting", 
"accounting.payment.application.autocreate", "Y", delegator)
+    if ("Y" != autoCreate) {
+        logInfo("payment application not automatically created because config 
is not set to Y")
+        return success()
+    }
+
+    Map createPaymentApplicationCtx = [:]
+    if (parameters.invoiceId) {
+        GenericValue invoice = from("Invoice").where("invoiceId", 
parameters.invoiceId).queryOne()
+        if (invoice) {
+            BigDecimal invoiceTotal = InvoiceWorker.getInvoiceTotal(invoice)
+
+            Map isInvoiceInForeignCurrencyResp = run service: 
'isInvoiceInForeignCurrency', with: [invoiceId: invoice.invoiceId]
+            if (ServiceUtil.isError(isInvoiceInForeignCurrencyResp)) return 
isInvoiceInForeignCurrencyResp
+
+            EntityConditionBuilder exprBldr = new EntityConditionBuilder()
+            EntityCondition expr = exprBldr.AND() {
+                NOT_EQUAL(statusId: 'PMNT_CONFIRMED')
+                EQUALS(partyIdFrom: invoice.partyId)
+                EQUALS(partyIdTo: invoice.partyIdFrom)
+            }
+            if (isInvoiceInForeignCurrencyResp.isForeign) {
+                expr = exprBldr.AND(expr) {
+                    EQUALS(actualCurrencyAmount: invoiceTotal)
+                    EQUALS(actualCurrencyUomId: invoice.currencyUomId)
+                }
+            } else {
+                expr = exprBldr.AND(expr) {
+                    EQUALS(amount: invoiceTotal)
+                    EQUALS(currencyUomId: invoice.currencyUomId)
+                }
+            }
+
+            GenericValue payment = from('Payment')
+                    .where(expr)
+                    .orderBy('effectiveDate')
+                    .queryFirst()
+
+            if (payment && from('PaymentApplication')
+                    .where('paymentId', payment.paymentId)
+                    .queryCount() == 0) {
+                createPaymentApplicationCtx.paymentId = payment.paymentId
+                createPaymentApplicationCtx.invoiceId = parameters.invoiceId
+                createPaymentApplicationCtx.amountApplied = 
isInvoiceInForeignCurrencyResp.isForeign
+                        ? payment.actualCurrencyAmount
+                        : payment.amount
+            }
+        }
+    }
+
+    if (parameters.paymentId) {
+        GenericValue payment = from("Payment").where(paymentId: 
parameters.paymentId).queryOne()
+
+        if (payment) {
+            EntityCondition expr = new EntityConditionBuilder().AND() {
+                NOT_IN(statusId: 
['INVOICE_READY','INVOICE_PAID','INVOICE_CANCELLED','INVOICE_WRITEOFF'])
+                EQUALS(partyIdFrom: payment.partyIdTo)
+                EQUALS(partyId: payment.partyIdFrom)
+            }
+
+            List invoices = from('Invoice')
+                    .where(expr)
+                    .orderBy('invoiceDate')
+                    .queryList()
+            String invoiceId
+            BigDecimal amountApplied
+            for (GenericValue invoice: invoices) {
+                boolean isPurchaseInvoice = 
EntityTypeUtil.hasParentType(delegator, 'InvoiceType', 'invoiceTypeId', 
invoice.invoiceTypeId, 'parentTypeId', 'PURCHASE_INVOICE')
+                boolean isSalesInvoice = 
EntityTypeUtil.hasParentType(delegator, 'InvoiceType', 'invoiceTypeId', 
invoice.invoiceTypeId, 'parentTypeId', 'SALES_INVOICE')
+
+                if (isPurchaseInvoice || isSalesInvoice) {
+                    BigDecimal invoiceTotal = 
InvoiceWorker.getInvoiceTotal(invoice)
+
+                    Map isInvoiceInForeignCurrencyResp = run service: 
'isInvoiceInForeignCurrency', with: [invoiceId: invoice.invoiceId]
+                    if (ServiceUtil.isError(isInvoiceInForeignCurrencyResp)) 
return isInvoiceInForeignCurrencyResp
+
+                    if (isInvoiceInForeignCurrencyResp.isForeign
+                            && 
invoiceTotal.compareTo(payment.actualCurrencyAmount) == 0
+                            && invoice.currencyUomId == 
payment.actualCurrencyUomId) {
+                        invoiceId = invoice.invoiceId
+                        amountApplied = payment.actualCurrencyAmount
+                    } else if (invoiceTotal.compareTo(payment.amount) == 0 && 
invoice.currencyUomId == payment.currencyUomId) {
+                        invoiceId = invoice.invoiceId
+                        amountApplied = payment.amount
+                    }
+
+                }
+            }
+
+            if (invoiceId) {
+                if (from('PaymentApplication')
+                        .where(invoiceId: invoiceId)
+                        .queryCount()) {
+                    createPaymentApplicationCtx.paymentId = 
parameters.paymentId
+                    createPaymentApplicationCtx.invoiceId = invoiceId
+                    createPaymentApplicationCtx.amountApplied = amountApplied
+                }
+            }
+        }
+    }
+
+    if (createPaymentApplicationCtx.paymentId &&
+            createPaymentApplicationCtx.invoiceId) {
+        Map createPaymentApplicationResp = run service: 
'createPaymentApplication', with: createPaymentApplicationCtx
+        if (ServiceUtil.isError(createPaymentApplicationResp)) return 
createPaymentApplicationResp
+
+        logInfo("payment application automatically created between invoiceId: 
$createPaymentApplicationCtx.invoiceId}" +
+                " and paymentId: ${createPaymentApplicationCtx.paymentId} for" 
+
+                " the amount: ${createPaymentApplicationCtx.amountApplied} 
(can be disabled in accounting.properties)")
+    }
+    return success()
+
+}
\ No newline at end of file
diff --git a/applications/accounting/minilang/payment/PaymentServices.xml 
b/applications/accounting/minilang/payment/PaymentServices.xml
index a878bc9..d7f112b 100644
--- a/applications/accounting/minilang/payment/PaymentServices.xml
+++ b/applications/accounting/minilang/payment/PaymentServices.xml
@@ -190,139 +190,4 @@ under the License.
         </else>
         </if-not-empty>
     </simple-method>
-    <simple-method method-name="createMatchingPaymentApplication" 
short-description="Create a payment application if either the invoice of 
payment could be found">
-        <property-to-field resource="accounting" 
property="accounting.payment.application.autocreate" field="autoCreate" 
default="Y"/>
-        <if-compare operator="not-equals" value="Y" field="autoCreate">
-            <log level="info" message="payment application not automatically 
created because config is not set to Y"/>
-            <return/>
-        </if-compare>
-
-        <if-not-empty field="parameters.invoiceId">
-            <entity-one entity-name="Invoice" value-field="invoice"/>
-            <if-not-empty field="invoice">
-                <call-class-method method-name="getInvoiceTotal" 
class-name="org.apache.ofbiz.accounting.invoice.InvoiceWorker" 
ret-field="invoiceTotal">
-                    <field field="invoice" type="GenericValue"/>
-                </call-class-method>
-                
-                <set field="checkInvoice.invoiceId" from="invoice.invoiceId"/>
-                <call-service service-name="isInvoiceInForeignCurrency" 
in-map-name="checkInvoice">
-                    <result-to-field result-name="isForeign"/>
-                </call-service>
-                <if-compare operator="equals" value="true" field="isForeign">
-                    <entity-condition entity-name="Payment" list="payments">
-                        <condition-list combine="and">
-                            <condition-expr field-name="statusId" 
value="PMNT_CONFIRMED" operator="not-equals"/>
-                            <condition-expr field-name="partyIdFrom" 
operator="equals" from-field="invoice.partyId"/>
-                            <condition-expr field-name="partyIdTo" 
operator="equals" from-field="invoice.partyIdFrom"/>
-                            <condition-expr field-name="actualCurrencyAmount" 
operator="equals" from-field="invoiceTotal"/>
-                            <condition-expr field-name="actualCurrencyUomId" 
operator="equals" from-field="invoice.currencyUomId"/>
-                        </condition-list>
-                        <order-by field-name="effectiveDate"/>
-                    </entity-condition>
-                    <else>
-                        <entity-condition entity-name="Payment" 
list="payments">
-                            <condition-list combine="and">
-                                <condition-expr field-name="statusId" 
value="PMNT_CONFIRMED" operator="not-equals"/>
-                                <condition-expr field-name="partyIdFrom" 
operator="equals" from-field="invoice.partyId"/>
-                                <condition-expr field-name="partyIdTo" 
operator="equals" from-field="invoice.partyIdFrom"/>
-                                <condition-expr field-name="amount" 
operator="equals" from-field="invoiceTotal"/>
-                                <condition-expr field-name="currencyUomId" 
operator="equals" from-field="invoice.currencyUomId"/>
-                            </condition-list>
-                            <order-by field-name="effectiveDate"/>
-                        </entity-condition>
-                    </else>
-                </if-compare>
-
-                <if-not-empty field="payments">
-                    <!-- check if already applied -->
-                    <entity-and entity-name="PaymentApplication" 
list="paymentAppls">
-                        <field-map field-name="paymentId" 
from-field="payments[0].paymentId"/>
-                    </entity-and>
-                    <if-empty field="paymentAppls">
-                        <set field="createAppl.paymentId" 
from-field="payments[0].paymentId"/>
-                        <set field="createAppl.invoiceId" 
from-field="parameters.invoiceId"/>
-                        <if-compare operator="equals" value="true" 
field="isForeign">
-                            <set field="createAppl.amountApplied" 
from-field="payments[0].actualCurrencyAmount"/>
-                            <else>
-                                <set field="createAppl.amountApplied" 
from-field="payments[0].amount"/>
-                            </else>
-                        </if-compare>
-                    </if-empty>
-                </if-not-empty>
-            </if-not-empty>
-        </if-not-empty>
-
-        <if-not-empty field="parameters.paymentId">
-            <entity-one entity-name="Payment" value-field="payment"/>
-            <if-not-empty field="payment">
-                        
-                <entity-condition entity-name="Invoice" list="invoices">
-                    <condition-list combine="and">
-                        <condition-expr field-name="statusId" 
value="INVOICE_READY" operator="not-equals"/>
-                        <condition-expr field-name="statusId" 
value="INVOICE_PAID" operator="not-equals"/>
-                        <condition-expr field-name="statusId" 
value="INVOICE_CANCELLED" operator="not-equals"/>
-                        <condition-expr field-name="statusId" 
value="INVOICE_WRITEOFF" operator="not-equals"/>
-                        <condition-expr field-name="partyIdFrom" 
from-field="payment.partyIdTo"/>
-                        <condition-expr field-name="partyId" 
from-field="payment.partyIdFrom"/>
-                    </condition-list>
-                    <order-by field-name="invoiceDate"/>
-                </entity-condition>
-                <iterate list="invoices" entry="invoice">
-                    <set field="isPurchaseInvoice" value="${groovy: 
org.apache.ofbiz.entity.util.EntityTypeUtil.hasParentType(delegator, 
'InvoiceType', 'invoiceTypeId', invoice.getString('invoiceTypeId'), 
'parentTypeId', 'PURCHASE_INVOICE')}" type="Boolean"/>
-                    <set field="isSalesInvoice" value="${groovy: 
org.apache.ofbiz.entity.util.EntityTypeUtil.hasParentType(delegator, 
'InvoiceType', 'invoiceTypeId', invoice.getString('invoiceTypeId'), 
'parentTypeId', 'SALES_INVOICE')}" type="Boolean"/>
-                    <if>
-                        <condition>
-                            <or>
-                                <if-compare field="isPurchaseInvoice" 
operator="equals" value="true" type="Boolean"/>
-                                <if-compare field="isSalesInvoice" 
operator="equals" value="true" type="Boolean"/>
-                            </or>
-                        </condition>
-                        <then>
-                            <call-class-method method-name="getInvoiceTotal" 
class-name="org.apache.ofbiz.accounting.invoice.InvoiceWorker" 
ret-field="invoiceTotal">
-                                <field field="invoice" type="GenericValue"/>
-                            </call-class-method>
-        
-                            <set field="checkInvoice.invoiceId" 
from="invoice.invoiceId"/>
-                            <call-service 
service-name="isInvoiceInForeignCurrency" in-map-name="checkInvoice">
-                                <result-to-field result-name="isForeign"/>
-                            </call-service>
-                            <if-compare operator="equals" value="true" 
field="isForeign">
-                                <if-compare-field field="invoiceTotal" 
operator="equals" to-field="payment.actualCurrencyAmount">
-                                    <if-compare-field 
field="invoice.currencyUomId" operator="equals" 
to-field="payment.actualCurrencyUomId">
-                                        <set field="invoiceId" 
from-field="invoice.invoiceId"/>
-                                        <set field="amountApplied" 
from-field="payment.actualCurrencyAmount"/>
-                                    </if-compare-field>
-                                </if-compare-field>
-                                <else>
-                                    <if-compare-field field="invoiceTotal" 
operator="equals" to-field="payment.amount">
-                                        <if-compare-field 
field="invoice.currencyUomId" operator="equals" 
to-field="payment.currencyUomId">
-                                            <set field="invoiceId" 
from-field="invoice.invoiceId"/>
-                                            <set field="amountApplied" 
from-field="payment.amount"/>
-                                        </if-compare-field>
-                                    </if-compare-field>
-                                </else>
-                            </if-compare>
-                        </then>
-                    </if>
-                </iterate>
-                <if-not-empty field="invoiceId">
-                    <entity-and entity-name="PaymentApplication" 
list="paymentAppls">
-                        <field-map field-name="invoiceId" 
from-field="invoiceId"/>
-                    </entity-and>
-                    <if-empty field="paymentAppls">
-                        <set field="createAppl.paymentId" 
from-field="parameters.paymentId"/>
-                        <set field="createAppl.invoiceId" 
from-field="invoiceId"/>
-                        <set field="createAppl.amountApplied" 
from-field="amountApplied"/>
-                    </if-empty>
-                </if-not-empty>
-            </if-not-empty>
-        </if-not-empty>
-
-        <if-not-empty field="createAppl.paymentId">
-            <if-not-empty field="createAppl.invoiceId">
-                <call-service service-name="createPaymentApplication" 
in-map-name="createAppl"/>
-                <log level="info" message="payment application automatically 
created between invoiceId: ${createAppl.invoiceId} and paymentId: 
${createAppl.paymentId} for the amount: ${createAppl.appliedAmount} (can be 
disabled in accounting.properties)"/>
-            </if-not-empty>
-        </if-not-empty>
-    </simple-method>
 </simple-methods>
diff --git a/applications/accounting/servicedef/services_payment.xml 
b/applications/accounting/servicedef/services_payment.xml
index 8a667e0..c244812 100644
--- a/applications/accounting/servicedef/services_payment.xml
+++ b/applications/accounting/servicedef/services_payment.xml
@@ -244,8 +244,8 @@ under the License.
         <attribute name="comments" type="String" mode="IN" optional="true"/>
     </service>
 
-    <service name="createMatchingPaymentApplication" engine="simple"
-        location="component://accounting/minilang/payment/PaymentServices.xml" 
invoke="createMatchingPaymentApplication" auth="true">
+    <service name="createMatchingPaymentApplication" engine="groovy"
+        
location="component://accounting/groovyScripts/payment/PaymentServices.groovy" 
invoke="createMatchingPaymentApplication" auth="true">
         <description>Create a payment application if either the invoice of 
payment could be found</description>
         <attribute name="paymentId" type="String" mode="IN" optional="true"/>
         <attribute name="invoiceId" type="String" mode="IN" optional="true"/>

Reply via email to