This is causing a validation problem. We used to have an issue on the contribution form which we eventually
resolved by removing net_amount as it's best calculated anyway
In order to make this changed I had to ensure Payment.create adds the net_amount & had
to do a couple of tweaks for the test to pass
$js = NULL;
// render backoffice payment fields only on offline mode
if (!$this->_mode) {
- $js = ['onclick' => "return verify( );"];
+ $js = ['onclick' => 'return verify( );'];
$this->add('select', 'payment_instrument_id',
ts('Payment Method'),
$attributes['fee_amount']
);
$this->addRule('fee_amount', ts('Please enter a valid monetary value for Fee Amount.'), 'money');
-
- $this->add('text', 'net_amount', ts('Net Amount'),
- $attributes['net_amount']
- );
- $this->addRule('net_amount', ts('Please enter a valid monetary value for Net Amount.'), 'money');
}
$buttonName = $this->_refund ? ts('Record Refund') : ts('Record Payment');
if ($self->_paymentType == 'refund' && $fields['total_amount'] != abs($self->_refund)) {
$errors['total_amount'] = ts('Refund amount must equal refund due amount.');
}
- $netAmt = (float) $fields['total_amount'] - (float) CRM_Utils_Array::value('fee_amount', $fields, 0);
- if (!empty($fields['net_amount']) && $netAmt != $fields['net_amount']) {
- $errors['net_amount'] = ts('Net amount should be equal to the difference between payment amount and fee amount.');
- }
+
if ($self->_paymentProcessor['id'] === 0 && empty($fields['payment_instrument_id'])) {
$errors['payment_instrument_id'] = ts('Payment method is a required field');
}
$trxn = new CRM_Financial_DAO_FinancialTrxn();
$trxn->copyValues($params);
+ if (isset($params['fee_amount']) && is_numeric($params['fee_amount'])) {
+ if (!isset($params['total_amount'])) {
+ $trxn->fetch();
+ $params['total_amount'] = $trxn->total_amount;
+ }
+ $trxn->net_amount = $params['total_amount'] - $params['fee_amount'];
+ }
+
if (empty($params['id']) && !CRM_Utils_Rule::currencyCode($trxn->currency)) {
$trxn->currency = CRM_Core_Config::singleton()->defaultCurrency;
}
*
* @return array
* Array of financial transactions which are payments, if error an array with an error id and error message
+ *
+ * @throws \CiviCRM_API3_Exception
*/
function civicrm_api3_payment_get($params) {
$financialTrxn = [];
if (isset($params['trxn_id'])) {
$params['financial_trxn_id.trxn_id'] = $params['trxn_id'];
}
- $eft = civicrm_api3('EntityFinancialTrxn', 'get', $params);
+ $eftParams = $params;
+ unset($eftParams['return']);
+ // @todo - why do we fetch EFT params at all?
+ $eft = civicrm_api3('EntityFinancialTrxn', 'get', $eftParams);
if (!empty($eft['values'])) {
$eftIds = [];
foreach ($eft['values'] as $efts) {
* @param array $params
* Input parameters.
*
- * @throws API_Exception
* @return array
* Api result array
+ *
+ * @throws \CiviCRM_API3_Exception
*/
function civicrm_api3_payment_delete($params) {
return civicrm_api3('FinancialTrxn', 'delete', $params);
* @return array
* Api result array
*
- * @throws \API_Exception
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
'title' => ts('Total Payment Amount'),
'type' => CRM_Utils_Type::T_FLOAT,
],
+ 'fee_amount' => [
+ 'title' => ts('Fee Amount'),
+ 'type' => CRM_Utils_Type::T_FLOAT,
+ ],
'payment_processor_id' => [
'name' => 'payment_processor_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Payment Date'),
'type' => CRM_Utils_Type::T_TIMESTAMP,
],
+ 'financial_trxn_id' => [
+ 'title' => ts('Payment ID'),
+ 'type' => CRM_Utils_Type::T_INT,
+ 'api.aliases' => ['payment_id', 'id'],
+ ],
];
}
</tr>
<tr class="crm-payment-form-block-fee_amount"><td class="label">{$form.fee_amount.label}</td><td{$valueStyle}>{$form.fee_amount.html|crmMoney:$currency:'XXX':'YYY'}<br />
<span class="description">{ts}Processing fee for this transaction (if applicable).{/ts}</span></td></tr>
- <tr class="crm-payment-form-block-net_amount"><td class="label">{$form.net_amount.label}</td><td>{$form.net_amount.html|crmMoney:$currency:'':1}<br />
- <span class="description">{ts}Net value of the payment (Total Amount minus Fee).{/ts}</span></td></tr>
</table>
</div>
{/if}
$this->validateAllPayments();
}
+ /**
+ * Test net amount is set when fee amount is passed in.
+ *
+ * @throws \CRM_Core_Exception
+ */
+ public function testNetAmount() {
+ $order = $this->createPendingParticipantOrder();
+ $payment = $this->callAPISuccess('Payment', 'create', ['order_id' => $order['id'], 'total_amount' => 10, 'fee_amount' => .25]);
+ $this->assertEquals('9.75', $this->callAPISuccessGetValue('Payment', ['id' => $payment['id'], 'return' => 'net_amount']));
+ }
+
/**
* Test create payment api for pay later contribution with partial payment.
*
'is_primary',
],
],
+ 'FinancialTrxn' => [
+ 'cant_update' => [
+ // Altering fee amount will also cause net_amount to be recalculated.
+ 'fee_amount',
+ ],
+ ],
'Navigation' => [
'cant_update' => [
// Weight is deliberately altered when this is changed - skip.