/*
 * 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.
 */
import org.apache.ofbiz.accounting.invoice.InvoiceWorker
import org.apache.ofbiz.base.util.Debug
import org.apache.ofbiz.base.util.UtilDateTime
import org.apache.ofbiz.base.util.UtilFormatOut
import org.apache.ofbiz.base.util.UtilProperties
import org.apache.ofbiz.entity.condition.EntityCondition
import org.apache.ofbiz.entity.condition.EntityOperator
import org.apache.ofbiz.entity.GenericValue
import org.apache.ofbiz.entity.util.EntityUtil
import org.apache.ofbiz.service.ModelService
import org.apache.ofbiz.service.ServiceUtil
import java.sql.Timestamp

def createPayment() {
    if (!security.hasEntityPermission("ACCOUNTING", "_CREATE", parameters.userLogin) && (!security.hasEntityPermission("PAY_INFO", "_CREATE", parameters.userLogin) && userLogin.partyId != parameters.partyIdFrom && userLogin.partyId != parameters.partyIdTo)) {
        return error(UtilProperties.getResourceBundleMap("AccountingUiLabels", locale)?.AccountingCreatePaymentPermissionError)
    }

    GenericValue payment = makeValue("Payment")
    payment.paymentId = parameters.paymentId ?: delegator.getNextSeqId("Payment")
    paymentId = payment.paymentId
    parameters.statusId = parameters.statusId ?: "PMNT_NOT_PAID"

    if (parameters.paymentMethodId) {
        GenericValue paymentMethod = from("PaymentMethod").where("paymentMethodId", parameters.paymentMethodId).queryOne()
        if (parameters.paymentMethodTypeId != paymentMethod.paymentMethodTypeId) {
            logInfo("Replacing passed payment method type [" + parameters.paymentMethodTypeId + "] with payment method type [" + paymentMethod.paymentMethodTypeId + "] for payment method [" + parameters.paymentMethodId +"]")
            parameters.paymentMethodTypeId = paymentMethod.paymentMethodTypeId
        }
    }

    if (parameters.paymentPreferenceId) {
        GenericValue orderPaymentPreference = from("OrderPaymentPreference").where("orderPaymentPreferenceId", parameters.paymentPreferenceId).queryOne()
        parameters.paymentId = parameters.paymentId ?: orderPaymentPreference.paymentMethodId
        parameters.paymentMethodTypeId = parameters.paymentMethodTypeId ?: orderPaymentPreference.paymentMethodTypeId
    }

    if (!parameters.paymentMethodTypeId) {
        return error(UtilProperties.getResourceBundleMap("AccountingUiLabels", locale)?.AccountingPaymentMethodIdPaymentMethodTypeIdNullError)
    }

    payment.setNonPKFields(parameters)
    payment.effectiveDate = payment.effectiveDate ?: UtilDateTime.nowTimestamp()
    delegator.create(payment)
    Map result = success()
    result.paymentId = paymentId
    return result
}
def getInvoicePaymentInfoList() {
    // Create a list with information on payment due dates and amounts for the invoice
    GenericValue invoice;
    List invoicePaymentInfoList = []
    if (!parameters.invoice) {
        invoice = from("Invoice").where("invoiceId", parameters.invoiceId).queryOne()
    } else {
        invoice = parameters.invoice
    }

    BigDecimal invoiceTotalAmount = InvoiceWorker.getInvoiceTotal(invoice)
    BigDecimal invoiceTotalAmountPaid = InvoiceWorker.getInvoiceApplied(invoice)

    List invoiceTerms = from("InvoiceTerm").where("invoiceId", invoice.invoiceId).queryList()

    BigDecimal remainingAppliedAmount = invoiceTotalAmountPaid
    BigDecimal computedTotalAmount = (BigDecimal) 0

    Map invoicePaymentInfo = [:]

    for (invoiceTerm in invoiceTerms) {
        termType = from("TermType").where("termTypeId", invoiceTerm.termTypeId).cache(true).queryOne()
        if ("FIN_PAYMENT_TERM" == termType.parentTypeId) {
            invoicePaymentInfo = [:]
            invoicePaymentInfo.invoiceId = invoice.invoiceId
            invoicePaymentInfo.invoiceTermId = invoiceTerm.invoiceTermId
            invoicePaymentInfo.termTypeId = invoiceTerm.termTypeId
            invoicePaymentInfo.dueDate = UtilDateTime.getDayEnd(invoice.invoiceDate, invoiceTerm.termDays)

            BigDecimal invoiceTermAmount = (invoiceTerm.termValue * invoiceTotalAmount ) / 100
            invoicePaymentInfo.amount = invoiceTermAmount
            computedTotalAmount = computedTotalAmount + (BigDecimal) invoicePaymentInfo.amount

            if (remainingAppliedAmount >= invoiceTermAmount) {
                invoicePaymentInfo.paidAmount = invoiceTermAmount
                remainingAppliedAmount = remainingAppliedAmount - invoiceTermAmount
            } else {
                invoicePaymentInfo.paidAmount = remainingAppliedAmount
                remainingAppliedAmount = (BigDecimal) 0
            }
            invoicePaymentInfo.outstandingAmount = invoicePaymentInfo.amount - invoicePaymentInfo.paidAmount
            invoicePaymentInfoList.add(invoicePaymentInfo)
        }
    }

    if (remainingAppliedAmount > 0.0 || invoiceTotalAmount <= 0.0 || computedTotalAmount < invoiceTotalAmount) {
        invoicePaymentInfo = [:]
        invoiceTerm = from("InvoiceTerm").where("invoiceId", invoice.invoiceId, "termTypeId", "FIN_PAYMENT_TERM").queryFirst()
        if (invoiceTerm) {
            invoicePaymentInfo.termTypeId = invoiceTerm.termTypeId
            invoicePaymentInfo.dueDate = UtilDateTime.getDayEnd(invoice.invoiceDate, invoiceTerm.termDays)
        } else {
            invoicePaymentInfo.dueDate = UtilDateTime.getDayEnd(invoice.invoiceDate)
        }
        invoicePaymentInfo.invoiceId = invoice.invoiceId
        invoicePaymentInfo.amount = invoiceTotalAmount - computedTotalAmount
        invoicePaymentInfo.paidAmount = remainingAppliedAmount
        invoicePaymentInfo.outstandingAmount = invoicePaymentInfo.amount - invoicePaymentInfo.paidAmount
        invoicePaymentInfoList.add(invoicePaymentInfo)
    }
    Map result = success()
    result.invoicePaymentInfoList = invoicePaymentInfoList
    return result
}
def updatePayment() {
    Map lookupPayment = makeValue("Payment")
    lookupPayment.setPKFields(parameters)
    GenericValue payment = from("Payment").where("paymentId", lookupPayment.paymentId).queryOne()
    if (!security.hasEntityPermission("ACCOUNTING", "_UPDATE", parameters.userLogin) &&
        (!security.hasEntityPermission("PAY_INFO", "_UPDATE", parameters.userLogin) &&
        userLogin.partyId != payment.partyIdFrom && userLogin.partyId != payment.partyIdTo)) {
        return error(UtilProperties.getResourceBundleMap("AccountingUiLabels", locale)?.AccountingUpdatePaymentPermissionError)
    }
    if ("PMNT_NOT_PAID" != payment.statusId) {
        // check if only status change
        GenericValue newPayment = makeValue("Payment")
        GenericValue oldPayment = makeValue("Payment")
        newPayment.setNonPKFields(payment)
        oldPayment.setNonPKFields(payment)
        newPayment.setNonPKFields(parameters)

        // fields :- comments, paymentRefNum, finAccountTransId, statusIhStatus does not allow an update of the information are editable for Payment
        oldPayment.statusId = newPayment.statusId
        oldPayment.comments = newPayment.comments
        oldPayment.paymentRefNum = newPayment.paymentRefNum ?: null
        oldPayment.finAccountTransId = newPayment.finAccountTransId ?: null
        if (!oldPayment.equals(newPayment)) {
            return error(UtilProperties.getResourceBundleMap("AccountingUiLabels", locale)?.AccountingPSUpdateNotAllowedBecauseOfStatus)
        }
    }
    statusIdSave = payment.statusId  // do not allow status change here
    payment.setNonPKFields(parameters)
    payment.statusId = statusIdSave  // do not allow status change here
    payment.effectiveDate = payment.effectiveDate ?: UtilDateTime.nowTimestamp()
    if (payment.paymentMethodId) {
        paymentMethod = from("PaymentMethod").where("paymentMethodId", payment.paymentMethodId).queryOne()
        if (payment.paymentMethodTypeId != paymentMethod.paymentMethodTypeId) {
            logInfo("Replacing passed payment method type [" + parameters.paymentMethodTypeId + "] with payment method type [" +
                paymentMethod.paymentMethodTypeId + "] for payment method [" + parameters.paymentMethodId +"]")
        }
        payment.paymentMethodTypeId = paymentMethod.paymentMethodTypeId
    }
    payment.store()
    if (parameters.statusId) {
        if (parameters.statusId != statusIdSave) {
            Map param = dispatcher.getDispatchContext().makeValidContext('setPaymentStatus', ModelService.IN_PARAM, parameters)
            param.paymentId = payment.paymentId
            serviceResult = run service: 'setPaymentStatus', with: param
            if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult)
        }
    }
    return success()
}
def createPaymentAndApplicationForParty() {
    paymentAmount = 0
    List invoiceIds = []
    Map result = success()
    parameters.invoices.each { invoice ->
        if ("INVOICE_READY" == invoice.statusId) {
            Map serviceContext = dispatcher.getDispatchContext().makeValidContext('getInvoicePaymentInfoList', ModelService.IN_PARAM, invoice)
            serviceContext.userLogin = userLogin
            serviceResult = run service: 'getInvoicePaymentInfoList', with: serviceContext
            if (ServiceUtil.isError(serviceResult)) return serviceResult
            invoicePaymentInfo = serviceResult.invoicePaymentInfoList[0]
            paymentAmount += invoicePaymentInfo.outstandingAmount
        } else {
            return error(UtilProperties.getMessage("AccountingUiLabels", "AccountingInvoicesRequiredInReadyStatus", parameters.locale))
        }
    }
    if (paymentAmount > 0) {
        serviceResult = run service: 'getPartyAccountingPreferences', with: parameters
        if (ServiceUtil.isError(serviceResult)) return serviceResult
        partyAcctgPreference = serviceResult.partyAccountingPreference
        Map createPaymentMap = [:]
        createPaymentMap.paymentTypeId = "VENDOR_PAYMENT"
        createPaymentMap.partyIdFrom = parameters.organizationPartyId
        createPaymentMap.currencyUomId = partyAcctgPreference.baseCurrencyUomId
        createPaymentMap.partyIdTo = parameters.partyId
        createPaymentMap.statusId = "PMNT_SENT"
        createPaymentMap.amount = paymentAmount
        createPaymentMap.paymentMethodTypeId = parameters.paymentMethodTypeId
        createPaymentMap.paymentMethodId = parameters.paymentMethodId
        createPaymentMap.paymentRefNum = parameters.checkStartNumber
        createPaymentMap.userLogin = userLogin
        serviceResult = run service: 'createPayment', with: createPaymentMap
        if (ServiceUtil.isError(serviceResult)) return serviceResult
        paymentId = serviceResult.paymentId
        result.paymentId = paymentId

        parameters.invoices.each {invoice ->
        if ("INVOICE_READY" == invoice.statusId) {
            Map serviceContext = dispatcher.getDispatchContext().makeValidContext('getInvoicePaymentInfoList', ModelService.IN_PARAM, invoice)
            serviceContext.userLogin = userLogin
            serviceResult = run service: 'getInvoicePaymentInfoList', with: serviceContext
            if (ServiceUtil.isError(serviceResult)) return serviceResult
            invoicePaymentInfo = serviceResult.invoicePaymentInfoList[0]
            if (invoicePaymentInfo.outstandingAmount > 0) {
                Map createPaymentApplicationMap = [:]
                createPaymentApplicationMap.paymentId =  paymentId
                createPaymentApplicationMap.amountApplied = invoicePaymentInfo.outstandingAmount
                createPaymentApplicationMap.invoiceId = invoice.invoiceId
                serviceResult = run service: 'createPaymentApplication', with: createPaymentApplicationMap
                if (ServiceUtil.isError(serviceResult)) return serviceResult
            }
        }
        invoiceIds.add(invoice.invoiceId)
        }
    }
    result.invoiceIds = invoiceIds
    result.amount =  paymentAmount
    return result
}
def getPaymentRunningTotal(){
    paymentIds = parameters.paymentIds;
    runningTotal = 0;
    payments = from("Payment").where(EntityCondition.makeCondition("paymentId", EntityOperator.IN, paymentIds)).queryList()
    if (payments) {
        for (GenericValue payment : payments) {
            runningTotal = runningTotal + payment.amount;
        }
    }

    if (parameters.organizationPartyId) {
        serviceCtx = [
                organizationPartyId: parameters.organizationPartyId,
                userLogin: userLogin
        ]
        serviceResult = dispatcher.runSync('getPartyAccountingPreferences', serviceCtx);
        partyAcctgPreference = serviceResult.partyAccountingPreference;

        if (partyAcctgPreference.baseCurrencyUomId) {
            currencyUomId = partyAcctgPreference.baseCurrencyUomId;
        } else {
            currencyUomId = UtilProperties.getPropertyValue('general.properties', 'currency.uom.id.default');
        }
    } else  {
        currencyUomId = UtilProperties.getPropertyValue('general.properties', 'currency.uom.id.default');
    }

    paymentRunningTotal = UtilFormatOut.formatCurrency(runningTotal, currencyUomId, locale);

    result = success()
    result.paymentRunningTotal = paymentRunningTotal
    return result
}
def createPaymentContent() {
    GenericValue newEntity = makeValue("PaymentContent")
    newEntity.setPKFields(parameters, true)
    newEntity.setNonPKFields(parameters, true)

    if (!newEntity.fromDate) {
        Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
        newEntity.fromDate  = nowTimestamp
    }
    newEntity.create()

    result = run service: 'updateContent', with: parameters
    if (ServiceUtil.isError(result)) return result

    Map result = success()
    result.contentId = newEntity.contentId
    result.paymentId = newEntity.paymentId
    result.paymentContentTypeId = newEntity.paymentContentTypeId
    return result
}
//TODO: This can be converted into entity-auto with a seca rule for updateContent
def updatePaymentContent() {
    serviceResult = success()
    GenericValue lookupPKMap = makeValue("PaymentContent")
    lookupPKMap.setPKFields(parameters, true)

    GenericValue lookedUpValue = findOne("PaymentContent", lookupPKMap, false)
    if (lookedUpValue) {
        lookedUpValue.setNonPKFields(parameters)
        lookedUpValue.store()
        result = run service: 'updateContent', with: parameters
        if (ServiceUtil.isError(result)) return result
        return serviceResult
    } else {
        return ServiceUtil.returnError("Error getting Payment Content")
    }
}
def massChangePaymentStatus() {
    serviceResult = success()
    Map setPaymentStatusMap = [:]
    parameters.paymentIds.each{ paymentId ->
        setPaymentStatusMap.paymentId = paymentId
        setPaymentStatusMap.statusId = parameters.statusId
        setPaymentStatusMap.userLogin = parameters.userLogin
        result = run service: 'setPaymentStatus', with: setPaymentStatusMap
        if (ServiceUtil.isError(result)) return result
        setPaymentStatusMap.clear()
    }
    return serviceResult
}
def getInvoicePaymentInfoListByDueDateOffset(){

    filteredInvoicePaymentInfoList = []

    Timestamp asOfDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp(), (long) parameters.daysOffset);

    exprList = [EntityCondition.makeCondition("invoiceTypeId", EntityOperator.EQUALS, parameters.invoiceTypeId),
                EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "INVOICE_CANCELLED"),
                EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "INVOICE_PAID")
    ]
    if (parameters.partyId) {
        exprList.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, parameters.partyId))
    }
    if (parameters.partyIdFrom) {
        exprList.add(EntityCondition.makeCondition("partyIdFrom", EntityOperator.EQUALS, parameters.partyIdFrom))
    }

    condition = EntityCondition.makeCondition(exprList, EntityOperator.AND);

    invoices = from("Invoice").where(condition).orderBy("invoiceDate").queryList();

    if (invoices) {
        for (GenericValue invoice : invoices) {
            getInvoicePaymentInfoListInMap = [:]
            getInvoicePaymentInfoListInMap.put("invoice", invoice);
            getInvoicePaymentInfoListInMap.put("userLogin", userLogin);
            serviceResult = run service: 'getInvoicePaymentInfoList', with: getInvoicePaymentInfoListInMap
            if (ServiceUtil.isError(serviceResult)) return result
            invoicePaymentInfoList = serviceResult.invoicePaymentInfoList;
            if (invoicePaymentInfoList) {
                invoicePaymentInfoList.each { invoicePaymentInfo ->
                    if (invoicePaymentInfo.outstandingAmount.compareTo(BigDecimal.ZERO) > 0 && invoicePaymentInfo.dueDate.before(asOfDate)) {
                        filteredInvoicePaymentInfoList.add(invoicePaymentInfo);
                    }
                }
            }
        }
    }

    result = success()
    result.invoicePaymentInfoList = filteredInvoicePaymentInfoList
    return result
}

def getPaymentGroupReconciliationId() {
    paymentGroupMember = from("PaymentGroupMember").where("paymentGroupId", parameters.paymentGroupId).queryFirst()
    glReconciliationId = null;
    Map result = success()
    if (paymentGroupMember) {
        payment = paymentGroupMember.getRelatedOne('Payment', false)
        finAccountTrans = payment.getRelatedOne('FinAccountTrans', false)
        if (finAccountTrans) {
            glReconciliationId = finAccountTrans.glReconciliationId
        }
    }
    result.glReconciliationId = glReconciliationId
    return result
}

def createPaymentAndApplication() {
    Map result = success()
    Map createPaymentCtx = dispatcher.getDispatchContext().makeValidContext('createPayment', 'IN', parameters)
    Map createPaymentResp = dispatcher.runSync('createPayment', createPaymentCtx)

    if (ServiceUtil.isError(createPaymentResp)) return createPaymentResp

    Map createPaymentApplicationCtx = dispatcher.getDispatchContext().makeValidContext('createPaymentApplication', 'IN', parameters)
    createPaymentApplicationCtx.paymentId = createPaymentResp.paymentId
    createPaymentApplicationCtx.amountApplied = parameters.amount
    Map createPaymentApplicationResp = dispatcher.runSync('createPaymentApplication', createPaymentApplicationCtx)

    if (ServiceUtil.isError(createPaymentApplicationResp)) return createPaymentApplicationResp

    result.put("paymentId", createPaymentResp.paymentId)
    result.put("paymentApplicationId", createPaymentApplicationResp.paymentApplicationId)
    return result

}

def createFinAccoutnTransFromPayment() {
    serviceResult = success()
    Map createFinAccountTransMap = dispatcher.getDispatchContext().makeValidContext('setPaymentStatus', ModelService.IN_PARAM, parameters)
    createFinAccountTransMap.finAccountTransTypeId = 'WITHDRAWAL'
    createFinAccountTransMap.partyId  = parameters.organizationPartyId
    createFinAccountTransMap.transactionDate = UtilDateTime.nowTimestamp()
    createFinAccountTransMap.entryDate = UtilDateTime.nowTimestamp()
    createFinAccountTransMap.statusId = 'FINACT_TRNS_CREATED'
    createFinAccountTransMap.comments = "Pay to ${parameters.partyId} for invoice Ids - ${parameters.invoiceIds}"
    result = run service: 'createFinAccountTrans', with: createFinAccountTransMap
    if (ServiceUtil.isError(result)) {
        return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result))
    }
    Map updatePaymentMap = [:]
    updatePaymentMap.finAccountTransId = result.finAccountTransId
    updatePaymentMap.paymentId = parameters.paymentId
    result = run service: 'updatePayment', with: updatePaymentMap
    if (ServiceUtil.isError(result)) {
        return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result))
    }
    return serviceResult
}

def quickSendPayment() {
    Map result = success()
    Map updatePaymentCtx = dispatcher.getDispatchContext().makeValidContext('updatePayment', 'IN', parameters)
    Map updatePaymentResp = dispatcher.runSync('updatePayment', updatePaymentCtx)

    if (ServiceUtil.isError(updatePaymentResp)) return updatePaymentResp

    Map setPaymentStatusCtx = dispatcher.getDispatchContext().makeValidContext('setPaymentStatus', 'IN', parameters)
    setPaymentStatusCtx.statusId = "PMNT_SENT"
    Map setPaymentStatusResp = dispatcher.runSync('setPaymentStatus', setPaymentStatusCtx)

    if (ServiceUtil.isError(setPaymentStatusResp)) return setPaymentStatusResp

    return result

}

/**
 * Service to cancel payment batch
 */
def cancelPaymentBatch() {
    List<GenericValue> paymentGroupMemberAndTransList = from("PmtGrpMembrPaymentAndFinAcctTrans").where("paymentGroupId", parameters.paymentGroupId).queryList()

    if (paymentGroupMemberAndTransList) {
        GenericValue paymentGroupMemberAndTrans = EntityUtil.getFirst(paymentGroupMemberAndTransList)
        if ("FINACT_TRNS_APPROVED" == paymentGroupMemberAndTrans.finAccountTransStatusId) {
            return error(UtilProperties.getMessage('AccountingErrorUiLabels', 'AccountingTransactionIsAlreadyReconciled', locale))
        }

        for (GenericValue paymentGroupMember : paymentGroupMemberAndTransList) {
            Map expirePaymentGroupMemberMap = dispatcher.getDispatchContext().makeValidContext("expirePaymentGroupMember", "IN", paymentGroupMember)
            result = runService("expirePaymentGroupMember", expirePaymentGroupMemberMap)
            if (ServiceUtil.isError(result)) return result

            GenericValue finAccountTrans = from("FinAccountTrans").where("finAccountTransId", paymentGroupMember.finAccountTransId).queryOne()
            if (finAccountTrans) {
                Map setFinAccountTransStatusMap = dispatcher.getDispatchContext().makeValidContext("setFinAccountTransStatus", "IN", finAccountTrans)
                setFinAccountTransStatusMap.statusId = "FINACT_TRNS_CANCELED"
                result = runService("setFinAccountTransStatus", setFinAccountTransStatusMap)
                if (ServiceUtil.isError(result)) return result
            }
        }
    }
}

def getPayments() {
    payments = []
    if (parameters.paymentGroupId) {
        paymentGroupMembers = from("PaymentGroupMember").where("paymentGroupId", parameters.paymentGroupId).filterByDate().queryList()
        if (paymentGroupMembers) {
            paymentIds = EntityUtil.getFieldListFromEntityList(paymentGroupMembers, "paymentId", true)
            payments = from("Payment").where(EntityCondition.makeCondition("paymentId", EntityOperator.IN, paymentIds)).queryList()
        }
    }
    if (parameters.finAccountTransId) {
        payments = from("Payment").where("finAccountTransId", parameters.finAccountTransId).queryList()
    }
    result = success()
    result.payments = payments
    return result
}

def cancelCheckRunPayments() {
    paymentGroupMemberAndTransList = from("PmtGrpMembrPaymentAndFinAcctTrans").where("paymentGroupId", parameters.paymentGroupId).queryList()
    if (paymentGroupMemberAndTransList) {
        paymentGroupMemberAndTrans = EntityUtil.getFirst(paymentGroupMemberAndTransList)
        if ("FINACT_TRNS_APPROVED" != paymentGroupMemberAndTrans.finAccountTransStatusId) {
            for (GenericValue paymentGroupMemberAndTrans : paymentGroupMemberAndTransList) {
                payment = from("Payment").where("paymentId", paymentGroupMemberAndTrans.paymentId).queryOne()
                Map voidPaymentMap = dispatcher.getDispatchContext().makeValidContext("voidPayment", "IN", payment)
                result = runService("voidPayment", voidPaymentMap)
                if (ServiceUtil.isError(result)) return result
                Map expirePaymentGroupMemberMap = dispatcher.getDispatchContext().makeValidContext("expirePaymentGroupMember", "IN", paymentGroupMemberAndTrans)
                result = runService("expirePaymentGroupMember", expirePaymentGroupMemberMap)
                if (ServiceUtil.isError(result)) return result
            }
        } else {
            return error(UtilProperties.getMessage("AccountingErrorUiLabels", "AccountingCheckIsAlreadyIssued", locale))
        }
    }
    return success()
}
