if (empty($contribution->id)) {
// (only) on 'create', make sure that a valid currency is set (CRM-16845)
if (!CRM_Utils_Rule::currencyCode($contribution->currency)) {
- $config = CRM_Core_Config::singleton();
- $contribution->currency = $config->defaultCurrency;
+ $contribution->currency = CRM_Core_Config::singleton()->defaultCurrency;
}
}
$params['contribution'] = $contribution;
self::recordFinancialAccounts($params);
+ if (self::isUpdateToRecurringContribution($params)) {
+ CRM_Contribute_BAO_ContributionRecur::updateOnNewPayment(
+ $params['contribution_recur_id'],
+ $contributionStatus[$params['contribution_status_id']]
+ );
+ }
+
// reset the group contact cache for this group
CRM_Contact_BAO_GroupContactCache::remove();
return $result;
}
+ /**
+ * Is this contribution updating an existing recurring contribution.
+ *
+ * We need to upd the status of the linked recurring contribution if we have a new payment against it, or the initial
+ * pending payment is being confirmed (or failing).
+ *
+ * @param array $params
+ *
+ * @return bool
+ */
+ public static function isUpdateToRecurringContribution($params) {
+ if (!empty($params['contribution_recur_id']) && empty($params['id'])) {
+ return TRUE;
+ }
+ if (empty($params['prevContribution']) || empty($params['contribution_status_id'])) {
+ return FALSE;
+ }
+ if (empty($params['contribution_recur_id']) && empty($params['prevContribution']->contribution_recur_id)) {
+ return FALSE;
+ }
+ $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
+ if ($params['prevContribution']->contribution_status_id == array_search('Pending', $contributionStatus)) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
/**
* Get defaults for new entity.
* @return array
}
/**
+ * Combine all the exportable fields from the lower level objects.
+ *
+ * @param bool $checkPermission
+ *
* @return array
+ * array of exportable Fields
*/
- public static function &exportableFields() {
+ public static function &exportableFields($checkPermission = TRUE) {
if (!self::$_exportableFields) {
if (!self::$_exportableFields) {
self::$_exportableFields = array();
$fields = array_merge($impFields, $typeField, $contributionStatus, $contributionPage, $optionField, $expFieldProduct,
$expFieldsContrib, $contributionNote, $contributionRecurId, $extraFields, $softCreditFields, $financialAccount, $premiums,
- CRM_Core_BAO_CustomField::getFieldsForImport('Contribution')
+ CRM_Core_BAO_CustomField::getFieldsForImport('Contribution', FALSE, FALSE, FALSE, $checkPermission)
);
self::$_exportableFields = $fields;
{$additionalClause}
";
- $dao = CRM_Core_DAO::executeQuery($query, CRM_Core_DAO::$_nullArray);
+ $dao = CRM_Core_DAO::executeQuery($query);
while ($dao->fetch()) {
$paymentDetails[$dao->id] = array(
'contribution_recur_id' => $contributionParams['contribution_recur_id'],
'options' => array('limit' => 1),
));
+ if (!empty($contributionParams['contribution_recur_id'])) {
+ $recurringContribution = civicrm_api3('ContributionRecur', 'getsingle', array(
+ 'id' => $contributionParams['contribution_recur_id'],
+ ));
+ if (!empty($recurringContribution['campaign_id'])) {
+ // CRM-17718 the campaign id on the contribution recur record should get precedence.
+ $contributionParams['campaign_id'] = $recurringContribution['campaign_id'];
+ }
+ }
+
$contributionParams['skipLineItem'] = TRUE;
$contributionParams['status_id'] = 'Pending';
- $contributionParams['financial_type_id'] = $templateContribution['financial_type_id'];
+ if (isset($contributionParams['financial_type_id'])) {
+ // Give precedence to passed in type.
+ $contribution->financial_type_id = $contributionParams['financial_type_id'];
+ }
+ else {
+ $contributionParams['financial_type_id'] = $templateContribution['financial_type_id'];
+ }
$contributionParams['contact_id'] = $templateContribution['contact_id'];
$contributionParams['source'] = empty($templateContribution['source']) ? ts('Recurring contribution') : $templateContribution['source'];
$createContribution = civicrm_api3('Contribution', 'create', $contributionParams);
$statusId = $params['contribution']->contribution_status_id;
// CRM-13964 partial payment
- if (CRM_Utils_Array::value('contribution_status_id', $params) == array_search('Partially paid', $contributionStatuses)
+ if ($contributionStatus == 'Partially paid'
&& !empty($params['partial_payment_total']) && !empty($params['partial_amount_pay'])
) {
$partialAmtPay = $params['partial_amount_pay'];
$balanceTrxnParams['status_id'] = $statusId;
$balanceTrxnParams['payment_instrument_id'] = $params['contribution']->payment_instrument_id;
$balanceTrxnParams['check_number'] = CRM_Utils_Array::value('check_number', $params);
+ if (!empty($balanceTrxnParams['from_financial_account_id']) &&
+ ($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'];
}
CRM_Price_BAO_LineItem::getLineItemArray($params, $entityID, str_replace('civicrm_', '', $entityTable), $isRelatedId);
}
- if (CRM_Utils_Array::value('contribution_status_id', $params) != array_search('Failed', $contributionStatuses) &&
- !(CRM_Utils_Array::value('contribution_status_id', $params) == array_search('Pending', $contributionStatuses) && !$params['contribution']->is_pay_later)
+ if ($contributionStatus != 'Failed' &&
+ !($contributionStatus == 'Pending' && !$params['contribution']->is_pay_later)
) {
$skipRecords = TRUE;
$pendingStatus = array(
- array_search('Pending', $contributionStatuses),
- array_search('In Progress', $contributionStatuses),
+ 'Pending',
+ 'In Progress',
);
- if (in_array(CRM_Utils_Array::value('contribution_status_id', $params), $pendingStatus)) {
+ if (in_array($contributionStatus, $pendingStatus)) {
$relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' "));
$params['to_financial_account_id'] = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId);
}
if ($contributionStatus == 'Refunded') {
$trxnParams['trxn_date'] = !empty($params['contribution']->cancel_date) ? $params['contribution']->cancel_date : date('YmdHis');
}
-
+ //CRM-16259, set is_payment flag for non pending status
+ if (!in_array(CRM_Utils_Array::value('contribution_status_id', $params), $pendingStatus)) {
+ $trxnParams['is_payment'] = 1;
+ }
if (!empty($params['payment_processor'])) {
$trxnParams['payment_processor_id'] = $params['payment_processor'];
}
}
}
+ /**
+ * Is there only one line item attached to the contribution.
+ *
+ * @param int $id
+ * Contribution ID.
+ *
+ * @return bool
+ * @throws \CiviCRM_API3_Exception
+ */
+ public static function isSingleLineItem($id) {
+ $lineItemCount = civicrm_api3('LineItem', 'getcount', array('id' => $id));
+ return ($lineItemCount == 1);
+ }
+
/**
* Complete an order.
*
'campaign_id',
'receive_date',
);
+ if (self::isSingleLineItem($primaryContributionID)) {
+ $inputContributionWhiteList[] = 'financial_type_id';
+ }
$contributionParams = array_merge(array(
'contribution_status_id' => 'Completed',
}
}
+ /**
+ * 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);
+ }
+
}