/** * Record adjusted amount. * * @param int $updatedAmount * @param int $paidAmount * @param int $contributionId * * @param int $taxAmount * @param bool $updateAmountLevel * * @return bool|\CRM_Core_BAO_FinancialTrxn */ public static function recordAdjustedAmt($updatedAmount, $paidAmount, $contributionId, $taxAmount = NULL, $updateAmountLevel = NULL) { $pendingAmount = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId); $pendingAmount = CRM_Utils_Array::value('total_amount', $pendingAmount, 0); $balanceAmt = $updatedAmount - $paidAmount; if ($paidAmount != $pendingAmount) { $balanceAmt -= $pendingAmount; } $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $partiallyPaidStatusId = array_search('Partially paid', $contributionStatuses); $pendingRefundStatusId = array_search('Pending refund', $contributionStatuses); $completedStatusId = array_search('Completed', $contributionStatuses); $updatedContributionDAO = new CRM_Contribute_BAO_Contribution(); $adjustedTrxn = $skip = FALSE; if ($balanceAmt) { if ($balanceAmt > 0 && $paidAmount != 0) { $contributionStatusVal = $partiallyPaidStatusId; } elseif ($balanceAmt < 0 && $paidAmount != 0) { $contributionStatusVal = $pendingRefundStatusId; } elseif ($paidAmount == 0) { //skip updating the contribution status if no payment is made $skip = TRUE; $updatedContributionDAO->cancel_date = 'null'; $updatedContributionDAO->cancel_reason = NULL; } // update contribution status and total amount without trigger financial code // as this is handled in current BAO function used for change selection $updatedContributionDAO->id = $contributionId; if (!$skip) { $updatedContributionDAO->contribution_status_id = $contributionStatusVal; } $updatedContributionDAO->total_amount = $updatedContributionDAO->net_amount = $updatedAmount; $updatedContributionDAO->fee_amount = 0; $updatedContributionDAO->tax_amount = $taxAmount; if (!empty($updateAmountLevel)) { $updatedContributionDAO->amount_level = $updateAmountLevel; } $updatedContributionDAO->save(); // adjusted amount financial_trxn creation $updatedContribution = CRM_Contribute_BAO_Contribution::getValues(array('id' => $contributionId), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($updatedContribution->financial_type_id, $relationTypeId); $adjustedTrxnValues = array('from_financial_account_id' => NULL, 'to_financial_account_id' => $toFinancialAccount, 'total_amount' => $balanceAmt, 'status_id' => $completedStatusId, 'payment_instrument_id' => $updatedContribution->payment_instrument_id, 'contribution_id' => $updatedContribution->id, 'trxn_date' => date('YmdHis'), 'currency' => $updatedContribution->currency); $adjustedTrxn = CRM_Core_BAO_FinancialTrxn::create($adjustedTrxnValues); } return $adjustedTrxn; }
static function getPartialPaymentWithType($entityId, $entityName = 'participant', $returnType = TRUE, $lineItemTotal = NULL) { $value = NULL; if (empty($entityName)) { return $value; } if ($entityName == 'participant') { $contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $entityId, 'contribution_id', 'participant_id'); $financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'financial_type_id'); if ($contributionId && $financialTypeId) { $statusId = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'); $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($financialTypeId, $relationTypeId); if (empty($lineItemTotal)) { $lineItemTotal = CRM_Price_BAO_LineItem::getLineTotal($entityId, 'civicrm_participant'); } $sqlFtTotalAmt = "\nSELECT SUM(ft.total_amount)\nFROM civicrm_financial_trxn ft\n LEFT JOIN civicrm_entity_financial_trxn eft ON (ft.id = eft.financial_trxn_id AND eft.entity_table = 'civicrm_contribution')\n LEFT JOIN civicrm_contribution c ON (eft.entity_id = c.id)\n LEFT JOIN civicrm_participant_payment pp ON (pp.contribution_id = c.id)\nWHERE pp.participant_id = {$entityId} AND ft.to_financial_account_id != {$toFinancialAccount}\n AND ft.status_id = {$statusId}\n"; $ftTotalAmt = CRM_Core_DAO::singleValueQuery($sqlFtTotalAmt); $value = 0; if ($ftTotalAmt) { $value = $paymentVal = $lineItemTotal - $ftTotalAmt; } if ($returnType) { $value = array(); if ($paymentVal < 0) { $value['refund_due'] = $paymentVal; } elseif ($paymentVal > 0) { $value['amount_owed'] = $paymentVal; } elseif ($lineItemTotal == $ftTotalAmt) { $value['full_paid'] = $ftTotalAmt; } } } } return $value; }
/** * Check financial transaction. * * @todo break this down into sensible functions - most calls to it only use a few lines out of the big if. * * @param array $contribution * @param string $context * @param int $instrumentId * @param array $extraParams */ public function _checkFinancialTrxn($contribution, $context, $instrumentId = NULL, $extraParams = array()) { $trxnParams = array('entity_id' => $contribution['id'], 'entity_table' => 'civicrm_contribution'); $trxn = current(CRM_Financial_BAO_FinancialItem::retrieveEntityFinancialTrxn($trxnParams, TRUE)); $params = array('id' => $trxn['financial_trxn_id']); if ($context == 'payLater') { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $compareParams = array('status_id' => 1, 'from_financial_account_id' => CRM_Contribute_PseudoConstant::financialAccountType($contribution['financial_type_id'], $relationTypeId)); } elseif ($context == 'refund') { $compareParams = array('to_financial_account_id' => 6, 'total_amount' => -100, 'status_id' => 7, 'trxn_date' => '2015-01-01 09:00:00', 'trxn_id' => 'the refund'); } elseif ($context == 'cancelPending') { $compareParams = array('to_financial_account_id' => 7, 'total_amount' => -100, 'status_id' => 3); } elseif ($context == 'changeFinancial' || $context == 'paymentInstrument') { $entityParams = array('entity_id' => $contribution['id'], 'entity_table' => 'civicrm_contribution', 'amount' => -100); $trxn = current(CRM_Financial_BAO_FinancialItem::retrieveEntityFinancialTrxn($entityParams)); $trxnParams1 = array('id' => $trxn['financial_trxn_id']); $compareParams = array('total_amount' => -100, 'status_id' => 1); if ($context == 'paymentInstrument') { $compareParams += array('to_financial_account_id' => CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount(4), 'payment_instrument_id' => 4); } else { $compareParams['to_financial_account_id'] = 12; } $this->assertDBCompareValues('CRM_Financial_DAO_FinancialTrxn', $trxnParams1, array_merge($compareParams, $extraParams)); $compareParams['total_amount'] = 100; if ($context == 'paymentInstrument') { $compareParams['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($instrumentId); $compareParams['payment_instrument_id'] = $instrumentId; } else { $compareParams['to_financial_account_id'] = 12; } } $this->assertDBCompareValues('CRM_Financial_DAO_FinancialTrxn', $params, array_merge($compareParams, $extraParams)); }
/** * Get list of payments displayed by Contribute_Page_PaymentInfo. * * @param int $id * @param $component * @param bool $getTrxnInfo * @param bool $usingLineTotal * * @return mixed */ public static function getPaymentInfo($id, $component, $getTrxnInfo = FALSE, $usingLineTotal = FALSE) { if ($component == 'event') { $entity = 'participant'; $entityTable = 'civicrm_participant'; $contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_ParticipantPayment', $id, 'contribution_id', 'participant_id'); if (!$contributionId) { if ($primaryParticipantId = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_Participant', $id, 'registered_by_id')) { $contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_ParticipantPayment', $primaryParticipantId, 'contribution_id', 'participant_id'); $id = $primaryParticipantId; } if (!$contributionId) { return; } } } $total = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId); $baseTrxnId = !empty($total['trxn_id']) ? $total['trxn_id'] : NULL; $isBalance = NULL; if ($baseTrxnId) { $isBalance = TRUE; } else { $baseTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contributionId); $baseTrxnId = $baseTrxnId['financialTrxnId']; $isBalance = FALSE; } if (!CRM_Utils_Array::value('total_amount', $total) || $usingLineTotal) { // for additional participants if ($entityTable == 'civicrm_participant') { $ids = CRM_Event_BAO_Participant::getParticipantIds($contributionId); $total = 0; foreach ($ids as $val) { $total += CRM_Price_BAO_LineItem::getLineTotal($val, $entityTable); } } else { $total = CRM_Price_BAO_LineItem::getLineTotal($id, $entityTable); } } else { $baseTrxnId = $total['trxn_id']; $total = $total['total_amount']; } $paymentBalance = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($id, $entity, FALSE, $total); $contributionIsPayLater = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'is_pay_later'); $feeRelationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Expense Account is' ")); $financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'financial_type_id'); $feeFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($financialTypeId, $feeRelationTypeId); if ($paymentBalance == 0 && $contributionIsPayLater) { $paymentBalance = $total; } $info['total'] = $total; $info['paid'] = $total - $paymentBalance; $info['balance'] = $paymentBalance; $info['id'] = $id; $info['component'] = $component; $info['payLater'] = $contributionIsPayLater; $rows = array(); if ($getTrxnInfo && $baseTrxnId) { // Need to exclude fee trxn rows so filter out rows where TO FINANCIAL ACCOUNT is expense account $sql = "\nSELECT ft.total_amount, con.financial_type_id, ft.payment_instrument_id, ft.trxn_date, ft.trxn_id, ft.status_id, ft.check_number\nFROM civicrm_contribution con\n LEFT JOIN civicrm_entity_financial_trxn eft ON (eft.entity_id = con.id AND eft.entity_table = 'civicrm_contribution')\n INNER JOIN civicrm_financial_trxn ft ON ft.id = eft.financial_trxn_id AND ft.to_financial_account_id != {$feeFinancialAccount}\nWHERE con.id = {$contributionId}\n"; // conditioned WHERE clause if ($isBalance) { // if balance trxn exists don't include details of it in transaction info $sql .= " AND ft.id != {$baseTrxnId} "; } $resultDAO = CRM_Core_DAO::executeQuery($sql); $statuses = CRM_Contribute_PseudoConstant::contributionStatus(); $financialTypes = CRM_Contribute_PseudoConstant::financialType(); while ($resultDAO->fetch()) { $paidByLabel = CRM_Core_PseudoConstant::getLabel('CRM_Core_BAO_FinancialTrxn', 'payment_instrument_id', $resultDAO->payment_instrument_id); $paidByName = CRM_Core_PseudoConstant::getName('CRM_Core_BAO_FinancialTrxn', 'payment_instrument_id', $resultDAO->payment_instrument_id); $val = array('total_amount' => $resultDAO->total_amount, 'financial_type' => $financialTypes[$resultDAO->financial_type_id], 'payment_instrument' => $paidByLabel, 'receive_date' => $resultDAO->trxn_date, 'trxn_id' => $resultDAO->trxn_id, 'status' => $statuses[$resultDAO->status_id]); if ($paidByName == 'Check') { $val['check_number'] = $resultDAO->check_number; } $rows[] = $val; } $info['transaction'] = $rows; } return $info; }
/** * This function is used to record partial payments for contribution * * @param array $contribution * * @param array $params * * @return object */ public static function recordPartialPayment($contribution, $params) { $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $pendingStatus = array(array_search('Pending', $contributionStatuses), array_search('In Progress', $contributionStatuses)); $statusId = array_search('Completed', $contributionStatuses); if (in_array(CRM_Utils_Array::value('contribution_status_id', $contribution), $pendingStatus)) { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $balanceTrxnParams['to_financial_account_id'] = CRM_Contribute_PseudoConstant::financialAccountType($contribution['financial_type_id'], $relationTypeId); } elseif (!empty($params['payment_processor'])) { $balanceTrxnParams['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getFinancialAccount($contribution['payment_processor'], 'civicrm_payment_processor', 'financial_account_id'); } elseif (!empty($params['payment_instrument_id'])) { $balanceTrxnParams['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contribution['payment_instrument_id']); } else { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); $queryParams = array(1 => array($relationTypeId, 'Integer')); $balanceTrxnParams['to_financial_account_id'] = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); } $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $fromFinancialAccountId = CRM_Contribute_PseudoConstant::financialAccountType($contribution['financial_type_id'], $relationTypeId); $balanceTrxnParams['from_financial_account_id'] = $fromFinancialAccountId; $balanceTrxnParams['total_amount'] = $params['total_amount']; $balanceTrxnParams['contribution_id'] = $params['contribution_id']; $balanceTrxnParams['trxn_date'] = !empty($params['contribution_receive_date']) ? $params['contribution_receive_date'] : date('YmdHis'); $balanceTrxnParams['fee_amount'] = CRM_Utils_Array::value('fee_amount', $params); $balanceTrxnParams['net_amount'] = CRM_Utils_Array::value('total_amount', $params); $balanceTrxnParams['currency'] = $contribution['currency']; $balanceTrxnParams['trxn_id'] = CRM_Utils_Array::value('contribution_trxn_id', $params, NULL); $balanceTrxnParams['status_id'] = $statusId; $balanceTrxnParams['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $params, $contribution['payment_instrument_id']); $balanceTrxnParams['check_number'] = CRM_Utils_Array::value('check_number', $params); if ($fromFinancialAccountId != NULL && ($statusId == array_search('Completed', $contributionStatuses) || $statusId == array_search('Partially paid', $contributionStatuses))) { $balanceTrxnParams['is_payment'] = 1; } if (!empty($params['payment_processor'])) { $balanceTrxnParams['payment_processor_id'] = $params['payment_processor']; } return CRM_Core_BAO_FinancialTrxn::create($balanceTrxnParams); }
/** * checks db values for financial item */ public function checkItemValues($contribution) { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType(4, $relationTypeId); $query = "SELECT eft1.entity_id, ft.total_amount, eft1.amount FROM civicrm_financial_trxn ft INNER JOIN civicrm_entity_financial_trxn eft ON (eft.financial_trxn_id = ft.id AND eft.entity_table = 'civicrm_contribution') \nINNER JOIN civicrm_entity_financial_trxn eft1 ON (eft1.financial_trxn_id = eft.financial_trxn_id AND eft1.entity_table = 'civicrm_financial_item')\nWHERE eft.entity_id = %1 AND ft.to_financial_account_id <> %2"; $queryParams[1] = array($contribution->id, 'Integer'); $queryParams[2] = array($toFinancialAccount, 'Integer'); $dao = CRM_Core_DAO::executeQuery($query, $queryParams); $amounts = array(100.0, 50.0); while ($dao->fetch()) { $this->assertEquals(150.0, $dao->total_amount, 'Mismatch of total amount paid.'); $this->assertEquals($dao->amount, array_pop($amounts), 'Mismatch of amount proportionally assigned to financial item'); } Contact::delete($this->_contactId); Event::delete($this->_eventId); }
/** * @param $updatedAmount * @param $paidAmount * @param $contributionId */ static function recordAdjustedAmt($updatedAmount, $paidAmount, $contributionId) { $balanceAmt = $updatedAmount - $paidAmount; $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $partiallyPaidStatusId = array_search('Partially paid', $contributionStatuses); $pendngRefundStatusId = array_search('Pending refund', $contributionStatuses); $completedStatusId = array_search('Completed', $contributionStatuses); $updatedContributionDAO = new CRM_Contribute_BAO_Contribution(); if ($balanceAmt) { if ($balanceAmt > 0 && $paidAmount != 0) { $contributionStatusVal = $partiallyPaidStatusId; } elseif ($balanceAmt < 0 && $paidAmount != 0) { $contributionStatusVal = $pendngRefundStatusId; } elseif ($paidAmount == 0) { $contributionStatusVal = $completedStatusId; $updatedContributionDAO->cancel_date = 'null'; $updatedContributionDAO->cancel_reason = NULL; } // update contribution status and total amount without trigger financial code // as this is handled in current BAO function used for change selection $updatedContributionDAO->id = $contributionId; $updatedContributionDAO->contribution_status_id = $contributionStatusVal; $updatedContributionDAO->total_amount = $updatedAmount; $updatedContributionDAO->save(); $ftDetail = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId); // adjusted amount financial_trxn creation if (empty($ftDetail['trxn_id'])) { $updatedContribution = CRM_Contribute_BAO_Contribution::getValues(array('id' => $contributionId), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($updatedContribution->financial_type_id, $relationTypeId); $adjustedTrxnValues = array('from_financial_account_id' => NULL, 'to_financial_account_id' => $toFinancialAccount, 'total_amount' => $balanceAmt, 'status_id' => CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'), 'payment_instrument_id' => $updatedContribution->payment_instrument_id, 'contribution_id' => $updatedContribution->id, 'trxn_date' => date('YmdHis'), 'currency' => $updatedContribution->currency); $adjustedTrxn = CRM_Core_BAO_FinancialTrxn::create($adjustedTrxnValues); } else { // update the financial trxn amount as well, as the fee selections has been updated if ($balanceAmt != $ftDetail['total_amount']) { CRM_Core_DAO::setFieldValue('CRM_Core_BAO_FinancialTrxn', $ftDetail['trxn_id'], 'total_amount', $balanceAmt); } } } }
/** * Function to validate financial type * * CRM-13231 * * @param integer $financialTypeId Financial Type id * * @access public * @static */ static function validateFinancialType($financialTypeId, $relationName = 'Expense Account is') { $expenseTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE '{$relationName}' ")); $financialAccount = CRM_Contribute_PseudoConstant::financialAccountType($financialTypeId, $expenseTypeId); if (!$financialAccount) { return CRM_Contribute_PseudoConstant::financialType($financialTypeId); } return FALSE; }
/** * create financial trxn and items when fee is charged * * @params params to create trxn entries * * @access public * @static */ static function recordFees($params) { $expenseTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Expense Account is' ")); $domainId = CRM_Core_Config::domainID(); $amount = 0; if (CRM_Utils_Array::value('prevContribution', $params)) { $amount = $params['prevContribution']->fee_amount; } $amount = $params['fee_amount'] - $amount; if (!$amount) { return FALSE; } $financialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $expenseTypeId); $params['trxnParams']['from_financial_account_id'] = $params['to_financial_account_id']; $params['trxnParams']['to_financial_account_id'] = $financialAccount; $params['trxnParams']['total_amount'] = $amount; $params['trxnParams']['fee_amount'] = $params['trxnParams']['net_amount'] = 0; $params['trxnParams']['status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'); $params['trxnParams']['contribution_id'] = isset($params['contribution']->id) ? $params['contribution']->id : $params['contribution_id']; $trxn = self::create($params['trxnParams']); if (!CRM_Utils_Array::value('entity_id', $params)) { $financialTrxnID = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($params['trxnParams']['contribution_id'], 'DESC'); $params['entity_id'] = $financialTrxnID['financialTrxnId']; } $fItemParams = array('financial_account_id' => $financialAccount, 'contact_id' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Domain', $domainId, 'contact_id'), 'created_date' => date('YmdHis'), 'transaction_date' => date('YmdHis'), 'amount' => $amount, 'description' => 'Fee', 'status_id' => CRM_Core_OptionGroup::getValue('financial_item_status', 'Paid', 'name'), 'entity_table' => 'civicrm_financial_trxn', 'entity_id' => $params['entity_id'], 'currency' => $params['trxnParams']['currency']); $trxnIDS['id'] = $trxn->id; $financialItem = CRM_Financial_BAO_FinancialItem::create($fItemParams, NULL, $trxnIDS); }
static function recordAdditionPayment($contributionId, $trxnsData, $paymentType = 'owed', $participantId = NULL) { $statusId = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'); $getInfoOf['id'] = $contributionId; $defaults = array(); $contributionDAO = CRM_Contribute_BAO_Contribution::retrieve($getInfoOf, $defaults, CRM_Core_DAO::$_nullArray); if ($paymentType == 'owed') { // build params for recording financial trxn entry $params['contribution'] = $contributionDAO; $params = array_merge($defaults, $params); $params['skipLineItem'] = TRUE; $params['partial_payment_total'] = $contributionDAO->total_amount; $params['partial_amount_pay'] = $trxnsData['total_amount']; $trxnsData['trxn_date'] = !empty($trxnsData['trxn_date']) ? $trxnsData['trxn_date'] : date('YmdHis'); // record the entry $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnsData); $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($contributionDAO->financial_type_id, $relationTypeId); $trxnId = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId, $contributionDAO->financial_type_id); $trxnId = $trxnId['trxn_id']; // update statuses // criteria for updates contribution total_amount == financial_trxns of partial_payments $sql = "SELECT SUM(ft.total_amount) as sum_of_payments\nFROM civicrm_financial_trxn ft\nLEFT JOIN civicrm_entity_financial_trxn eft\n ON (ft.id = eft.financial_trxn_id)\nWHERE eft.entity_table = 'civicrm_contribution'\n AND eft.entity_id = {$contributionId}\n AND ft.to_financial_account_id != {$toFinancialAccount}\n AND ft.status_id = {$statusId}\n"; $sumOfPayments = CRM_Core_DAO::singleValueQuery($sql); // update statuses if ($contributionDAO->total_amount == $sumOfPayments) { // update contribution status $contributionUpdate['id'] = $contributionId; $contributionUpdate['contribution_status_id'] = $statusId; $contributionUpdate['skipLineItem'] = TRUE; // note : not using the self::add method, // the reason because it performs 'status change' related code execution for financial records // which in 'Partial Paid' => 'Completed' is not useful, instead specific financial record updates // are coded below i.e. just updating financial_item status to 'Paid' $contributionDetails = CRM_Core_DAO::setFieldValue('CRM_Contribute_BAO_Contribution', $contributionId, 'contribution_status_id', $statusId); if ($participantId) { // update participant status $participantUpdate['id'] = $participantId; $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); $participantUpdate['status_id'] = array_search('Registered', $participantStatuses); CRM_Event_BAO_Participant::add($participantUpdate); } // update financial item statuses $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id'); $paidStatus = array_search('Paid', $financialItemStatus); $sqlFinancialItemUpdate = "\nUPDATE civicrm_financial_item fi\n LEFT JOIN civicrm_entity_financial_trxn eft\n ON (eft.entity_id = fi.id AND eft.entity_table = 'civicrm_financial_item')\nSET status_id = {$paidStatus}\nWHERE eft.financial_trxn_id = {$trxnId}\n"; CRM_Core_DAO::executeQuery($sqlFinancialItemUpdate); } } elseif ($paymentType == 'refund') { // build params for recording financial trxn entry $params['contribution'] = $contributionDAO; $params = array_merge($defaults, $params); $params['skipLineItem'] = TRUE; $trxnsData['trxn_date'] = !empty($trxnsData['trxn_date']) ? $trxnsData['trxn_date'] : date('YmdHis'); $trxnsData['total_amount'] = -$trxnsData['total_amount']; $trxnsData['status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', 'Refunded', 'name'); // record the entry $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnsData); // note : not using the self::add method, // the reason because it performs 'status change' related code execution for financial records // which in 'Pending Refund' => 'Completed' is not useful, instead specific financial record updates // are coded below i.e. just updating financial_item status to 'Paid' $contributionDetails = CRM_Core_DAO::setFieldValue('CRM_Contribute_BAO_Contribution', $contributionId, 'contribution_status_id', $statusId); // add financial item entry $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id'); $getLine['entity_id'] = $contributionDAO->id; $getLine['entity_table'] = 'civicrm_contribution'; $lineItemId = CRM_Price_BAO_LineItem::retrieve($getLine, CRM_Core_DAO::$_nullArray); $addFinancialEntry = array('transaction_date' => $financialTrxn->trxn_date, 'contact_id' => $contributionDAO->contact_id, 'amount' => $financialTrxn->total_amount, 'status_id' => array_search('Paid', $financialItemStatus), 'entity_id' => $lineItemId->id, 'entity_table' => 'civicrm_line_item'); $trxnIds['id'] = $financialTrxn->id; CRM_Financial_BAO_FinancialItem::create($addFinancialEntry, NULL, $trxnIds); if ($participantId) { // update participant status $participantUpdate['id'] = $participantId; $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); $participantUpdate['status_id'] = array_search('Registered', $participantStatuses); CRM_Event_BAO_Participant::add($participantUpdate); } } // activity creation if (!empty($financialTrxn)) { if ($participantId) { $inputParams['id'] = $participantId; $values = array(); $ids = array(); $component = 'event'; $entityObj = CRM_Event_BAO_Participant::getValues($inputParams, $values, $ids); $entityObj = $entityObj[$participantId]; } $activityType = $paymentType == 'refund' ? 'Refund' : 'Payment'; // creation of activity $activity = new CRM_Activity_DAO_Activity(); $activity->source_record_id = $financialTrxn->id; $activity->activity_type_id = CRM_Core_OptionGroup::getValue('activity_type', $activityType, 'name'); if (!$activity->find(TRUE)) { self::addActivityForPayment($entityObj, $financialTrxn, $activityType, $component); } } return $financialTrxn; }
/** * to create trxn entry if an event has discount. * * @param int $eventID event id * @param array $contributionParams contribution params. * * @static */ static function createDiscountTrxn($eventID, $contributionParams, $feeLevel) { // CRM-11124 $checkDiscount = CRM_Core_BAO_Discount::findSet($eventID, 'civicrm_event'); if (!empty($checkDiscount)) { $feeLevel = current($feeLevel); $priceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_event', $eventID, NULL); $query = "SELECT cpfv.amount FROM `civicrm_price_field_value` cpfv\nLEFT JOIN civicrm_price_field cpf ON cpfv.price_field_id = cpf.id\nWHERE cpf.price_set_id = %1 AND cpfv.label LIKE %2"; $params = array(1 => array($priceSetId, 'Integer'), 2 => array($feeLevel, 'String')); $mainAmount = CRM_Core_DAO::singleValueQuery($query, $params); $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Discounts Account is' ")); $contributionParams['trxnParams']['from_financial_account_id'] = CRM_Contribute_PseudoConstant::financialAccountType($contributionParams['contribution']->financial_type_id, $relationTypeId); if (CRM_Utils_Array::value('from_financial_account_id', $contributionParams['trxnParams'])) { $contributionParams['trxnParams']['total_amount'] = $mainAmount - $contributionParams['total_amount']; $contributionParams['trxnParams']['payment_processor_id'] = $contributionParams['trxnParams']['payment_instrument_id'] = $contributionParams['trxnParams']['check_number'] = $contributionParams['trxnParams']['trxn_id'] = $contributionParams['trxnParams']['net_amount'] = $contributionParams['trxnParams']['fee_amount'] = NULL; CRM_Core_BAO_FinancialTrxn::create($contributionParams['trxnParams']); } } return; }
/** * Create Accounts Receivable financial trxn entry for Completed Contribution. * * @param array $trxnParams * Financial trxn params * @param string $contributionParams * Contribution Params * * @return string */ public static function recordAlwaysAccountsReceivable(&$trxnParams, $contributionParams) { if (!self::checkContributeSettings('always_post_to_accounts_receivable')) { return NULL; } $statusId = $contributionParams['contribution']->contribution_status_id; $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $contributionStatus = empty($statusId) ? NULL : $contributionStatuses[$statusId]; $previousContributionStatus = empty($contributionParams['prevContribution']) ? NULL : $contributionStatuses[$contributionParams['prevContribution']->contribution_status_id]; // Return if contribution status is not completed. if (!($contributionStatus == 'Completed' && (empty($previousContributionStatus) || !empty($previousContributionStatus) && $previousContributionStatus == 'Pending' && $contributionParams['prevContribution']->is_pay_later == 0))) { return NULL; } $params = $trxnParams; $financialTypeID = CRM_Utils_Array::value('financial_type_id', $contributionParams) ? $contributionParams['financial_type_id'] : $contributionParams['prevContribution']->financial_type_id; $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $arAccountId = CRM_Contribute_PseudoConstant::financialAccountType($financialTypeID, $relationTypeId); $params['to_financial_account_id'] = $arAccountId; $params['status_id'] = array_search('Pending', $contributionStatuses); $params['is_payment'] = FALSE; $trxn = CRM_Core_BAO_FinancialTrxn::create($params); self::$_trxnIDs[] = $trxn->id; $trxnParams['from_financial_account_id'] = $params['to_financial_account_id']; }
static function changeFeeSelections($params, $participantId, $contributionId, $feeBlock, $lineItems, $paidAmount, $priceSetId) { $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $partiallyPaidStatusId = array_search('Partially paid', $contributionStatuses); $pendngRefundStatusId = array_search('Pending refund', $contributionStatuses); $fetchCon = array('id' => $contributionId); $contributionObj = CRM_Contribute_BAO_Contribution::retrieve($fetchCon, CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); $previousLineItems = CRM_Price_BAO_LineItem::getLineItems($participantId, 'participant'); CRM_Price_BAO_PriceSet::processAmount($feeBlock, $params, $lineItems); // get the submitted foreach ($feeBlock as $id => $values) { CRM_Price_BAO_LineItem::format($id, $params, $values, $submittedLineItems); $submittedFieldId[] = CRM_Utils_Array::retrieveValueRecursive($submittedLineItems, 'price_field_id'); } $insertLines = $submittedLineItems; $submittedFieldValueIds = array_keys($submittedLineItems); foreach ($previousLineItems as $id => $previousLineItem) { // check through the submitted items if the previousItem exists, // if found in submitted items, do not use it for new item creations if (in_array($previousLineItem['price_field_value_id'], $submittedFieldValueIds)) { unset($insertLines[$previousLineItem['price_field_value_id']]); } } $submittedFields = implode(', ', $submittedFieldId); $submittedFieldValues = implode(', ', $submittedFieldValueIds); if (!empty($submittedFields) && !empty($submittedFieldValues)) { // if previous line item is not submitted in selection, update the line total and QTY to '0' $updateLineItem = "\nUPDATE civicrm_line_item li\nINNER JOIN civicrm_financial_item fi\n ON (li.id = fi.entity_id AND fi.entity_table = 'civicrm_line_item')\nINNER JOIN civicrm_entity_financial_trxn eft\n ON (eft.entity_id = fi.id AND eft.entity_table = 'civicrm_financial_item')\nSET li.qty = 0,\n li.line_total = 0.00,\n fi.amount = 0.00,\n eft.amount = 0.00\nWHERE (li.entity_table = 'civicrm_participant' AND li.entity_id = {$participantId}) AND\n (price_field_value_id NOT IN ({$submittedFieldValues}) OR price_field_id NOT IN ({$submittedFields}))\n"; CRM_Core_DAO::executeQuery($updateLineItem); } // insert new line items foreach ($insertLines as $valueId => $lineParams) { $lineParams['entity_table'] = 'civicrm_participant'; $lineParams['entity_id'] = $participantId; $lineObj = CRM_Price_BAO_LineItem::create($lineParams); // insert financial items // ensure entity_financial_trxn table has a linking of it. $prevItem = CRM_Financial_BAO_FinancialItem::add($lineObj, $contributionObj); } // insert new 'adjusted amount' transaction entry and update contribution entry. // ensure entity_financial_trxn table has a linking of it. $updatedAmount = $params['amount']; $balanceAmt = $updatedAmount - $paidAmount; if ($balanceAmt) { if ($balanceAmt > 0) { $contributionStatusVal = $partiallyPaidStatusId; } elseif ($balanceAmt < 0) { $contributionStatusVal = $pendngRefundStatusId; } // update contribution status and total amount without trigger financial code // as this is handled in current BAO function used for change selection $updatedContributionDAO = new CRM_Contribute_BAO_Contribution(); $updatedContributionDAO->id = $contributionId; $updatedContributionDAO->contribution_status_id = $contributionStatusVal; $updatedContributionDAO->total_amount = $updatedAmount; $updatedContributionDAO->save(); /* * adjusted amount financial_trxn creation, * adjusted amount line_item creation, * adjusted amount financial_item creations, * adjusted amount enitity_financial_trxn creation */ $updatedContribution = CRM_Contribute_BAO_Contribution::getValues(array('id' => $contributionId), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); $prevTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contributionId); $fetchPrevTrxn['id'] = $prevTrxnId['financialTrxnId']; $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($updatedContribution->financial_type_id, $relationTypeId); $adjustedTrxnValues = array('from_financial_account_id' => NULL, 'to_financial_account_id' => $toFinancialAccount, 'trxn_date' => date('YmdHis'), 'total_amount' => $balanceAmt, 'currency' => $updatedContribution->currency, 'status_id' => CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'), 'payment_instrument_id' => $updatedContribution->payment_instrument_id, 'contribution_id' => $updatedContribution->id); $adjustedTrxn = CRM_Core_BAO_FinancialTrxn::create($adjustedTrxnValues); // record line item $adjustPaymentLineParams = array('total_amount' => $updatedAmount, 'financial_type_id' => $updatedContribution->financial_type_id); $setId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', 'default_contribution_amount', 'id', 'name'); CRM_Price_BAO_LineItem::getLineItemArray($adjustPaymentLineParams); $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id'); $defaultPriceSet = current(CRM_Price_BAO_PriceSet::getSetDetail($setId)); $fieldID = key($defaultPriceSet['fields']); $adjustPaymentLineParams['line_item'][$setId][$fieldID]['entity_id'] = $updatedContribution->id; $adjustPaymentLineParams['line_item'][$setId][$fieldID]['entity_table'] = 'civicrm_contribution'; $adjustPaymentLine = CRM_Price_BAO_LineItem::create($adjustPaymentLineParams['line_item'][$setId][$fieldID]); // record financial item $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id'); $itemStatus = NULL; if ($updatedContribution->contribution_status_id == array_search('Pending refund', $contributionStatuses)) { $itemStatus = array_search('Paid', $financialItemStatus); } elseif ($updatedContribution->contribution_status_id == array_search('Partially paid', $contributionStatuses)) { $itemStatus = array_search('Partially paid', $financialItemStatus); } $params = array('transaction_date' => CRM_Utils_Date::isoToMysql($updatedContribution->receive_date), 'contact_id' => $updatedContribution->contact_id, 'amount' => $balanceAmt, 'currency' => $updatedContribution->currency, 'entity_table' => 'civicrm_line_item', 'entity_id' => $adjustPaymentLine->id, 'description' => ($adjustPaymentLine->qty != 1 ? $lineItem->qty . ' of ' : '') . ' ' . $adjustPaymentLine->label, 'status_id' => $itemStatus, 'financial_account_id' => $prevItem->financial_account_id); CRM_Financial_BAO_FinancialItem::create($params, NULL, array('id' => $adjustedTrxn->id)); } //activity creation$contributionStatuses self::addActivityForSelection($participantId, 'Change Registration'); }