Skip to content

Commit

Permalink
[REF] extract internals of Payment.create into function on BAO class.
Browse files Browse the repository at this point in the history
This is a partial of civicrm#13330 - trying
to separate out the main code move from the changes. My only change was to change the name to
addPayment since that is what we are doing but here are some additionaly thoughts.

1) I'm inclined to put the class onto a new pseudo-bao CRM_Finanial_BAO_Payment. We already have this
pseudo-entity on the api level & it gives us a way to build up a place for the functions we are migrating
towards.

2) I think we should consider changing the input parameters to this function to be
- contributionID, total_amount & line_items or in some way limiting the parameters tha
t get passed through. We have historically gotten ourselves in trouble by
having people hacking in another parameter to go through whereas the strength of the api
is clear inputs & outputs. I note the api will need to support
'is_email_receipt' as will this fn & the CRM_Contribute_Form_AdditionalPayment::emailReceipt
should be moved off the form layer - possibly to our new BAO

3) I think the exceptions need to be CRM_Core_Exceptions if thrown in the BAO although this is kinda cosmetic

Change-Id: Ib5caf0d878e9c5cc735cb1a20c640f61da2dbfc6
  • Loading branch information
eileenmcnaughton committed Dec 31, 2018
1 parent 0e35e2a commit 5625fdf
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 68 deletions.
86 changes: 86 additions & 0 deletions CRM/Contribute/BAO/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -4477,6 +4477,92 @@ public static function isSingleLineItem($id) {
return ($lineItemCount == 1);
}

/**
* Function to process additional payment for partial and refund contributions.
*
* This function is called via API payment.create function. All forms that add payments
* should use this.
*
* @param array $params
* - contribution_id
* - total_amount
* - line_item
* @return \CRM_Financial_DAO_FinancialTrxn
*
* @throws \API_Exception
* @throws \CRM_Core_Exception
*/
public static function addPayment($params) {
$contribution = civicrm_api3('Contribution', 'getsingle', ['id' => $params['contribution_id']]);
$contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($contribution['contribution_status_id'], 'name');
if ($contributionStatus != 'Partially paid'
&& !($contributionStatus == 'Pending' && $contribution['is_pay_later'] == TRUE)
) {
throw new API_Exception('Please select a contribution which has a partial or pending payment');
}
else {
// Check if pending contribution
$fullyPaidPayLater = FALSE;
if ($contributionStatus == 'Pending') {
$cmp = bccomp($contribution['total_amount'], $params['total_amount'], 5);
// Total payment amount is the whole amount paid against pending contribution
if ($cmp == 0 || $cmp == -1) {
civicrm_api3('Contribution', 'completetransaction', ['id' => $contribution['id']]);
// Get the trxn
$trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
$ftParams = ['id' => $trxnId['financialTrxnId']];
$trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray);
$fullyPaidPayLater = TRUE;
}
else {
civicrm_api3('Contribution', 'create',
[
'id' => $contribution['id'],
'contribution_status_id' => 'Partially paid',
]
);
}
}
if (!$fullyPaidPayLater) {
$trxn = CRM_Core_BAO_FinancialTrxn::getPartialPaymentTrxn($contribution, $params);
if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) {
foreach ($params['line_item'] as $values) {
foreach ($values as $id => $amount) {
$p = ['id' => $id];
$check = CRM_Price_BAO_LineItem::retrieve($p, $defaults);
if (empty($check)) {
throw new API_Exception('Please specify a valid Line Item.');
}
// get financial item
$sql = "SELECT fi.id
FROM civicrm_financial_item fi
INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item'
WHERE li.contribution_id = %1 AND li.id = %2";
$sqlParams = [
1 => [$params['contribution_id'], 'Integer'],
2 => [$id, 'Integer'],
];
$fid = CRM_Core_DAO::singleValueQuery($sql, $sqlParams);
// Record Entity Financial Trxn
$eftParams = [
'entity_table' => 'civicrm_financial_item',
'financial_trxn_id' => $trxn->id,
'amount' => $amount,
'entity_id' => $fid,
];
civicrm_api3('EntityFinancialTrxn', 'create', $eftParams);
}
}
}
elseif (!empty($trxn)) {
CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn->id, $contribution['total_amount']);
}
}
}
return $trxn;

}

/**
* Complete an order.
*
Expand Down
70 changes: 2 additions & 68 deletions api/v3/Payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,74 +132,8 @@ function civicrm_api3_payment_create(&$params) {
civicrm_api3('Payment', 'cancel', $params);
$params['total_amount'] = $amount;
}
// Get contribution
$contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $params['contribution_id']));
$contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($contribution['contribution_status_id'], 'name');
if ($contributionStatus != 'Partially paid'
&& !($contributionStatus == 'Pending' && $contribution['is_pay_later'] == TRUE)
) {
throw new API_Exception('Please select a contribution which has a partial or pending payment');
}
else {
// Check if pending contribution
$fullyPaidPayLater = FALSE;
if ($contributionStatus == 'Pending') {
$cmp = bccomp($contribution['total_amount'], $params['total_amount'], 5);
// Total payment amount is the whole amount paid against pending contribution
if ($cmp == 0 || $cmp == -1) {
civicrm_api3('Contribution', 'completetransaction', array('id' => $contribution['id']));
// Get the trxn
$trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
$ftParams = array('id' => $trxnId['financialTrxnId']);
$trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray);
$fullyPaidPayLater = TRUE;
}
else {
civicrm_api3('Contribution', 'create',
array(
'id' => $contribution['id'],
'contribution_status_id' => 'Partially paid',
)
);
}
}
if (!$fullyPaidPayLater) {
$trxn = CRM_Core_BAO_FinancialTrxn::getPartialPaymentTrxn($contribution, $params);
if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) {
foreach ($params['line_item'] as $values) {
foreach ($values as $id => $amount) {
$p = array('id' => $id);
$check = CRM_Price_BAO_LineItem::retrieve($p, $defaults);
if (empty($check)) {
throw new API_Exception('Please specify a valid Line Item.');
}
// get financial item
$sql = "SELECT fi.id
FROM civicrm_financial_item fi
INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item'
WHERE li.contribution_id = %1 AND li.id = %2";
$sqlParams = array(
1 => array($params['contribution_id'], 'Integer'),
2 => array($id, 'Integer'),
);
$fid = CRM_Core_DAO::singleValueQuery($sql, $sqlParams);
// Record Entity Financial Trxn
$eftParams = array(
'entity_table' => 'civicrm_financial_item',
'financial_trxn_id' => $trxn->id,
'amount' => $amount,
'entity_id' => $fid,
);
civicrm_api3('EntityFinancialTrxn', 'create', $eftParams);
}
}
}
elseif (!empty($trxn)) {
// Assign the lineitems proportionally
CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn->id, $contribution['total_amount']);
}
}
}
$trxn = CRM_Contribute_BAO_Contribution::addPayment($params);

$values = array();
_civicrm_api3_object_to_array_unique_fields($trxn, $values[$trxn->id]);
return civicrm_api3_create_success($values, $params, 'Payment', 'create', $trxn);
Expand Down

0 comments on commit 5625fdf

Please sign in to comment.