/*
 * 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.util.UtilAccounting
import org.apache.ofbiz.base.util.UtilDateTime
import org.apache.ofbiz.base.util.UtilMisc
import org.apache.ofbiz.base.util.UtilProperties
import org.apache.ofbiz.entity.GenericValue
import org.apache.ofbiz.entity.condition.EntityCondition
import org.apache.ofbiz.entity.condition.EntityOperator
import org.apache.ofbiz.party.party.PartyWorker

import java.sql.Timestamp

if (!fromDate) {
    return
}
if (!thruDate) {
    thruDate = UtilDateTime.nowTimestamp()
}
if (!parameters.glFiscalTypeId) {
    parameters.glFiscalTypeId = "ACTUAL"
}

uiLabelMap = UtilProperties.getResourceBundleMap("AccountingUiLabels", locale)
parametersFromDate = fromDate

// Setup the divisions for which the report is executed
List partyIds = PartyWorker.getAssociatedPartyIdsByRelationshipType(delegator, parameters.get('ApplicationDecorator|organizationPartyId'), 'GROUP_ROLLUP')
partyIds.add(parameters.get('ApplicationDecorator|organizationPartyId'))

// Get the group of account classes that will be used to position accounts in the proper section of the  Cash Flow statement
GenericValue glAccountClass = from("GlAccountClass").where("glAccountClassId", "CASH_EQUIVALENT").cache(true).queryOne()
List glAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(glAccountClass)

List cashFlowBalanceTotalList = []

// Find the last closed time period to get the fromDate for the transactions in the current period and the ending balances of the last closed period 
Map lastClosedTimePeriodResult = runService('findLastClosedDate', ["organizationPartyId":parameters.get('ApplicationDecorator|organizationPartyId'), "findDate": parametersFromDate,"userLogin":userLogin])
Timestamp periodClosingFromDate = (Timestamp)lastClosedTimePeriodResult.lastClosedDate
if (!periodClosingFromDate) {
    return
}
GenericValue lastClosedTimePeriod = (GenericValue)lastClosedTimePeriodResult.lastClosedTimePeriod
// Get the opening balances of Cash Account
Map openingCashBalances = [:]
if (lastClosedTimePeriod) {
    List timePeriodAndExprs = []
    timePeriodAndExprs.add(EntityCondition.makeCondition("organizationPartyId", EntityOperator.IN, partyIds))
    timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, glAccountClassIds))
    timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO))
    timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId))
    List lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList()
    lastTimePeriodHistories.each { lastTimePeriodHistory ->
        Map accountMap = ["glAccountId":lastTimePeriodHistory.glAccountId, "accountCode":lastTimePeriodHistory.accountCode, "accountName":lastTimePeriodHistory.accountName, "balance":lastTimePeriodHistory.getBigDecimal("endingBalance"), "D":lastTimePeriodHistory.getBigDecimal("postedDebits"), "C":lastTimePeriodHistory.getBigDecimal("postedCredits")]
        openingCashBalances.(lastTimePeriodHistory.glAccountId) = accountMap
    }
}
List mainAndExprs = []
mainAndExprs.add(EntityCondition.makeCondition("organizationPartyId", EntityOperator.IN, partyIds))
mainAndExprs.add(EntityCondition.makeCondition("isPosted", EntityOperator.EQUALS, "Y"))
mainAndExprs.add(EntityCondition.makeCondition("glFiscalTypeId", EntityOperator.EQUALS, parameters.glFiscalTypeId))
mainAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, glAccountClassIds))

// All GlAccount's transactions (from last closing period to parameter's fromDate) 
accountBalanceList = []
transactionTotals = []
balanceTotal = BigDecimal.ZERO
List openingCashBalanceAndExprs = mainAndExprs as LinkedList
openingCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, periodClosingFromDate))
openingCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN, parametersFromDate))
transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(openingCashBalanceAndExprs).orderBy("glAccountId").queryList()
transactionTotalsMap = [:]
transactionTotalsMap.putAll(openingCashBalances)
transactionTotals.each { transactionTotal ->
    Map accountMap = (Map)transactionTotalsMap.get(transactionTotal.glAccountId)
    if (!accountMap) {
        accountMap = UtilMisc.makeMapWritable(transactionTotal)
        accountMap.remove("debitCreditFlag")
        accountMap.remove("amount")
        accountMap.D = BigDecimal.ZERO
        accountMap.C = BigDecimal.ZERO
        accountMap.balance = BigDecimal.ZERO
    }
    if (accountMap.debitCreditFlag && accountMap.amount) {
        accountMap.remove("debitCreditFlag")
        accountMap.remove("amount")
    }
    if (transactionTotal.debitCreditFlag == "C") {
        accountMap.C = ((BigDecimal)accountMap.get("C")).add(transactionTotal.amount)
        accountMap.balance = (accountMap.balance).subtract(transactionTotal.amount)
    } else {
        accountMap.D = ((BigDecimal)accountMap.get("D")).add(transactionTotal.amount)
        accountMap.balance = (accountMap.balance).add(transactionTotal.amount)
    }

    transactionTotalsMap.put(transactionTotal.glAccountId, accountMap)
}
glAccountIdList = []
accountBalanceList = UtilMisc.sortMaps(transactionTotalsMap.values().asList(), UtilMisc.toList("accountCode"))
accountBalanceList.each { accountBalance ->
    balanceTotal = balanceTotal.add(accountBalance.balance)
}
openingCashBalanceTotal = balanceTotal
context.openingCashBalanceList = accountBalanceList
cashFlowBalanceTotalList.add("totalName":"AccountingOpeningCashBalance", "balance":balanceTotal)
openingTransactionKeySet = transactionTotalsMap.keySet()

// PERIOD CASH BALANCE 
// GlAccounts from parameter's fromDate to parameter's thruDate.
accountBalanceList = []
transactionTotals = []
balanceTotal = BigDecimal.ZERO
List periodCashBalanceAndExprs = mainAndExprs as LinkedList
periodCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, parametersFromDate))
periodCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN, thruDate))
transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(periodCashBalanceAndExprs).orderBy("glAccountId").queryList()
if (transactionTotals) {
    Map transactionTotalsMap = [:]
    balanceTotalCredit = BigDecimal.ZERO
    balanceTotalDebit = BigDecimal.ZERO
    transactionTotals.each { transactionTotal ->
        Map accountMap = (Map)transactionTotalsMap.get(transactionTotal.glAccountId)
        if (!accountMap) {
            accountMap = UtilMisc.makeMapWritable(transactionTotal)
            accountMap.remove("debitCreditFlag")
            accountMap.remove("amount")
            accountMap.D = BigDecimal.ZERO
            accountMap.C = BigDecimal.ZERO
            accountMap.balance = BigDecimal.ZERO
        }
        UtilMisc.addToBigDecimalInMap(accountMap, transactionTotal.debitCreditFlag, transactionTotal.amount)
        if ("D".equals(transactionTotal.debitCreditFlag)) {
            balanceTotalDebit = balanceTotalDebit.add(transactionTotal.amount)
        } else {
            balanceTotalCredit = balanceTotalCredit.add(transactionTotal.amount)
        }
        BigDecimal debitAmount = (BigDecimal)accountMap.D
        BigDecimal creditAmount = (BigDecimal)accountMap.C
        BigDecimal balance = debitAmount.subtract(creditAmount)
        accountMap.balance = balance
        transactionTotalsMap.(transactionTotal.glAccountId) = accountMap
    }
    accountBalanceList = UtilMisc.sortMaps(transactionTotalsMap.values().asList(), UtilMisc.toList("accountCode"))
    balanceTotal = balanceTotalDebit.subtract(balanceTotalCredit)
}
periodCashBalanceTotal = balanceTotal
context.periodCashBalanceList = accountBalanceList
context.periodCashBalanceList.add("accountName":uiLabelMap.AccountingTotalPeriodCashBalance, "balance":balanceTotal)
cashFlowBalanceTotalList.add("totalName":"AccountingPeriodCashBalance", "balance":balanceTotal)

// CLOSING BALANCE 
// GlAccounts from parameter's fromDate to parameter's thruDate.
accountBalanceList = []
balanceTotal = BigDecimal.ZERO
List transactionTotals = []
transactionTotals.addAll(new LinkedList(context.openingCashBalanceList))
transactionTotals.addAll(new LinkedList(context.periodCashBalanceList))
transactionTotals = UtilMisc.sortMaps(transactionTotals, UtilMisc.toList("accountCode"))
closingTransactionKeySet = []
if (transactionTotals) {
    Map transactionTotalsMap = [:]
    balanceTotalCredit = BigDecimal.ZERO
    balanceTotalDebit = BigDecimal.ZERO
    transactionTotals.each { transactionTotal ->
        if (transactionTotal.D != null) {
            if (transactionTotalsMap.(transactionTotal.glAccountId)) {
                totalDebitBalance = (transactionTotal.D).add(transactionTotalsMap.(transactionTotal.glAccountId).D)
                totalCreditBalance = (transactionTotal.C).add(transactionTotalsMap.(transactionTotal.glAccountId).C)
                if (transactionTotalsMap.(transactionTotal.glAccountId).D == 0 && transactionTotalsMap.(transactionTotal.glAccountId).C == 0) {
                    transactionTotalsMap.(transactionTotal.glAccountId).balance = (transactionTotal.balance).add(transactionTotalsMap.(transactionTotal.glAccountId).balance)
                } else {
                    transactionTotalsMap.(transactionTotal.glAccountId).D = totalDebitBalance
                    transactionTotalsMap.(transactionTotal.glAccountId).C = totalCreditBalance
                    transactionTotalsMap.(transactionTotal.glAccountId).balance = totalDebitBalance.subtract(totalCreditBalance)
                }
            } else {
                transactionTotalsMap.(transactionTotal.glAccountId) = transactionTotal
            }
            accountBalanceList = UtilMisc.sortMaps(transactionTotalsMap.values().asList(), UtilMisc.toList("accountCode"))
        }
    }
    closingTransactionKeySet = transactionTotalsMap.keySet()
}
accountBalanceList.each { accountBalance ->
    balanceTotal = balanceTotal.add(accountBalance.balance)
}
context.closingCashBalanceList = accountBalanceList
context.closingCashBalanceList.add("accountName":uiLabelMap.AccountingTotalClosingCashBalance, "balance":balanceTotal)

// Get differences of glAccount in closing and opening list and then add difference to opening list.
if (closingTransactionKeySet) {
    closingTransactionKeySet.removeAll(openingTransactionKeySet)
    closingTransactionKeySet.each { closingTransactionKey ->
        glAccount = from("GlAccount").where("glAccountId", closingTransactionKey).cache(true).queryOne()
        context.openingCashBalanceList.add(["glAccountId":glAccount.glAccountId, "accountName":glAccount.accountName, accountCode:glAccount.accountCode, balance:BigDecimal.ZERO, D:BigDecimal.ZERO, C:BigDecimal.ZERO])
    }
}
context.openingCashBalanceList.add(["accountName":uiLabelMap.AccountingTotalOpeningCashBalance, "balance":openingCashBalanceTotal])

// CASH FLOW STATEMENT ENDING BALANCE
// ENDING BALANCE = OPENING CASH BALANCE + PERIOD CASH BALANCE 
endingCashBalanceTotal = openingCashBalanceTotal.add(periodCashBalanceTotal)
cashFlowBalanceTotalList.add("totalName":"AccountingEndingCashBalance", "balance":endingCashBalanceTotal)
context.cashFlowBalanceTotalList = cashFlowBalanceTotalList
