"value", 'option_group_id' => "account_relationship", 'name' => "Grant Expense Account is", ]); $config = CRM_Core_Config::singleton(); $mkTime = mktime(0, 0, 0, $config->fiscalYearStart['M'], $config->fiscalYearStart['d'], $fiscalYear); $fiscalStartDate = date('Y-m-d', $mkTime); $fiscalEndDate = date('Y-m-d', strtotime($fiscalStartDate . '+ 1 year')); $qParams = [ 1 => [$fiscalYear, 'String'], 2 => [$fiscalStartDate, 'String'], 3 => [$fiscalEndDate, 'String'], 4 => [$paidStatusID, 'Integer'], 5 => [$accountRelationshipId, 'Integer'], ]; $where = ''; if (!empty($params['financial_type_id'])) { $where = 'WHERE cft.id = %6'; $qParams[6] = [$params['financial_type_id'], 'Integer']; } $grantBudgetTableName = CRM_AnnualGrantBudgets_DAO_GrantBudget::getTableName(); $sql = "SELECT cgb.id, cft.name, IFNULL(cgb.budget, 0) AS budget, SUM(CASE WHEN cg.id IS NULL THEN 0 ELSE IFNULL(trxn.total_amount, 0) END) as total_amount_granted, cft.id AS financial_type_id, cgb.note, cgb.is_reserved FROM civicrm_financial_type cft INNER JOIN " . GRANT_SCHOLARSHIP_CUSTOM_TABLE_NAME . " gs ON gs.entity_id = cft.id AND gs." . GRANT_SCHOLARSHIP_CUSTOM_FIELD . " = 1 LEFT JOIN " . $grantBudgetTableName . " cgb ON cgb.financial_type_id = cft.id AND cgb.fiscal_year = %1 LEFT JOIN civicrm_entity_financial_account cefa ON cefa.entity_table = 'civicrm_financial_type' AND cft.id = cefa.entity_id AND account_relationship = %5 LEFT JOIN civicrm_financial_trxn trxn ON trxn.from_financial_account_id = cefa.financial_account_id LEFT JOIN civicrm_entity_financial_trxn ceft on trxn.id = ceft.financial_trxn_id AND ceft.entity_table = 'civicrm_grant' LEFT JOIN civicrm_grant cg ON cg.id = ceft.entity_id AND cg.status_id IN (%4) AND cg." . GRANT_DATE_CHECK_FIELD . " >= %2 AND cg." . GRANT_DATE_CHECK_FIELD . " < %3 {$where} GROUP BY cft.id ORDER BY cft.name"; $result = CRM_Core_DAO::executeQuery($sql, $qParams); while ($result->fetch()) { $grantBudget[] = [ 'id' => $result->id, 'name' => $result->name, 'budget' => $result->budget, 'total_amount_granted' => $result->total_amount_granted, 'balance_amount' => $result->budget - $result->total_amount_granted, 'financial_type_id' => $result->financial_type_id, 'note' => $result->note, 'is_reserved' => $result->is_reserved, ]; if ($returnTotals) { $totals['budget'] += $result->budget; $totals['total_amount_granted'] += $result->total_amount_granted; $totals['balance_amount'] += $result->budget - $result->total_amount_granted; } } if ($returnTotals) { // Format as money. foreach ($totals as $k => $v) { $totals[$k] = CRM_Utils_Money::format($v); } return $totals; } return $grantBudget; } /** * Validate grant. * * @param $params array * @param $grantId Integer * * @return array An array of errors */ public static function checkBudget($params, $grantId) { $year = date('Y', strtotime($params[GRANT_DATE_CHECK_FIELD])); foreach ($params['financial_account'] as $k => $financialAccount) { if (!$financialAccount) { break; } $financialTypeId = self::getFinancialTypeFromGrantExpenseAccount($financialAccount); $grantBudget = civicrm_api3('GrantBudget', 'getbudget', [ 'financial_type_id' => $financialTypeId, 'fiscal_year' => $year, ])['values'][0]; if ($grantBudget) { $balanceAmount = $grantBudget['balance_amount']; $amountGranted = $params['multifund_amount'][$k]; // If there's a $grantId, we're updating an existing grant. Make sure we don't // double-count this money on validation. if ($grantId) { $oldGrantLineItem = civicrm_api3('EntityFinancialTrxn', 'get', [ 'sequential' => 1, 'return' => ["financial_trxn_id.total_amount", "financial_trxn_id.trxn_date"], 'entity_table' => "civicrm_grant", 'entity_id' => $grantId, 'financial_trxn_id.from_financial_account_id' => $financialAccount, ])['values'][0]; if ($oldGrantLineItem && $year == date('Y', strtotime($oldGrantLineItem['financial_trxn_id.trxn_date']))) { $amountGranted -= $oldGrantLineItem['financial_trxn_id.total_amount']; } } if ($balanceAmount < $amountGranted) { $budgetDisplay = CRM_Utils_Money::format($grantBudget['budget']); $totalGrantedDisplay = CRM_Utils_Money::format($grantBudget['total_amount_granted']); $balanceDisplay = CRM_Utils_Money::format($grantBudget['balance_amount']); $errors["multifund_amount[$k]"] = ts("The annual budget for this grant is $budgetDisplay. Grants totaling $totalGrantedDisplay have been made. $balanceDisplay remains."); } } } return $errors; } public static function getFinancialTypeFromGrantExpenseAccount($accountId) { $financialTypeId = civicrm_api3('EntityFinancialAccount', 'getvalue', [ 'return' => "entity_id", 'account_relationship' => "Grant Expense Account is", 'financial_account_id' => $accountId, 'entity_table' => "civicrm_financial_type", ]); return $financialTypeId; } }