drupal-civicrm/sites/all/modules/civicrm/CRM/Financial/Form/PaymentEdit.php
2018-01-14 13:10:16 +00:00

318 lines
11 KiB
PHP

<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_Financial_Form_PaymentEdit extends CRM_Core_Form {
/**
* The id of the financial trxn.
*
* @var int
*/
protected $_id;
/**
* The id of the related contribution ID
*
* @var int
*/
protected $_contributionID;
/**
* The variable which holds the information of a financial transaction
*
* @var array
*/
protected $_values;
/**
* Explicitly declare the form context.
*/
public function getDefaultContext() {
return 'create';
}
/**
* Set variables up before form is built.
*/
public function preProcess() {
$this->_action = CRM_Core_Action::UPDATE;
parent::preProcess();
$this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
$this->assign('id', $this->_id);
$this->_contributionID = CRM_Utils_Request::retrieve('contribution_id', 'Positive', $this);
$this->_values = civicrm_api3('FinancialTrxn', 'getsingle', array('id' => $this->_id));
if (!empty($this->_values['payment_processor_id'])) {
CRM_Core_Error::statusBounce(ts('You cannot update this payment'));
}
}
/**
* Set default values.
*
* @return array
*/
public function setDefaultValues() {
return $this->_values;
}
/**
* Build quickForm.
*/
public function buildQuickForm() {
CRM_Utils_System::setTitle(ts('Update Payment details'));
$paymentFields = $this->getPaymentFields();
$this->assign('paymentFields', $paymentFields);
foreach ($paymentFields as $name => $paymentField) {
if (!empty($paymentField['add_field'])) {
$attributes = array(
'entity' => 'FinancialTrxn',
'name' => $name,
);
$this->addField($name, $attributes, $paymentField['is_required']);
}
else {
$this->add($paymentField['htmlType'],
$name,
$paymentField['title'],
$paymentField['attributes'],
$paymentField['is_required']
);
}
}
$this->assign('currency', CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_Currency', $this->_values['currency'], 'symbol', 'name'));
$this->addFormRule(array(__CLASS__, 'formRule'), $this);
$this->addButtons(array(
array(
'type' => 'submit',
'name' => ts('Update'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
));
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param $self
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $self) {
$errors = array();
// if Credit Card is chosen and pan_truncation is not NULL ensure that it's value is numeric else throw validation error
if (CRM_Core_PseudoConstant::getName('CRM_Financial_DAO_FinancialTrxn', 'payment_instrument_id', $fields['payment_instrument_id']) == 'Credit Card' &&
!empty($fields['pan_truncation']) &&
!CRM_Utils_Rule::numeric($fields['pan_truncation'])
) {
$errors['pan_truncation'] = ts('Please enter a valid Card Number');
}
return $errors;
}
/**
* Process the form submission.
*/
public function postProcess() {
$params = array(
'id' => $this->_id,
'payment_instrument_id' => $this->_submitValues['payment_instrument_id'],
'trxn_id' => CRM_Utils_Array::value('trxn_id', $this->_submitValues),
'trxn_date' => CRM_Utils_Array::value('trxn_date', $this->_submitValues, date('YmdHis')),
);
$paymentInstrumentName = CRM_Core_PseudoConstant::getName('CRM_Financial_DAO_FinancialTrxn', 'payment_instrument_id', $params['payment_instrument_id']);
if ($paymentInstrumentName == 'Credit Card') {
$params['card_type_id'] = CRM_Utils_Array::value('card_type_id', $this->_submitValues);
$params['pan_truncation'] = CRM_Utils_Array::value('pan_truncation', $this->_submitValues);
}
elseif ($paymentInstrumentName == 'Check') {
$params['check_number'] = CRM_Utils_Array::value('check_number', $this->_submitValues);
}
$this->submit($params);
CRM_Core_Session::singleton()->pushUserContext(CRM_Utils_System::url(CRM_Utils_System::currentPath()));
}
/**
* Wrapper function to process form submission
*
* @param array $submittedValues
*
*/
protected function submit($submittedValues) {
// if payment instrument is changed then
// 1. Record a new reverse financial transaction with old payment instrument
// 2. Record a new financial transaction with new payment instrument
// 3. Add EntityFinancialTrxn records to relate with corresponding financial item and contribution
if ($submittedValues['payment_instrument_id'] != $this->_values['payment_instrument_id']) {
$previousFinanciaTrxn = $this->_values;
$newFinancialTrxn = $submittedValues;
unset($previousFinanciaTrxn['id'], $newFinancialTrxn['id']);
$previousFinanciaTrxn['trxn_date'] = CRM_Utils_Array::value('trxn_date', $submittedValues, date('YmdHis'));
$previousFinanciaTrxn['total_amount'] = -$previousFinanciaTrxn['total_amount'];
$previousFinanciaTrxn['net_amount'] = -$previousFinanciaTrxn['net_amount'];
$previousFinanciaTrxn['fee_amount'] = -$previousFinanciaTrxn['fee_amount'];
$previousFinanciaTrxn['contribution_id'] = $newFinancialTrxn['contribution_id'] = $this->_contributionID;
$newFinancialTrxn['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($submittedValues['payment_instrument_id']);
foreach (array('total_amount', 'fee_amount', 'net_amount', 'currency', 'is_payment', 'status_id') as $fieldName) {
$newFinancialTrxn[$fieldName] = $this->_values[$fieldName];
}
foreach (array($previousFinanciaTrxn, $newFinancialTrxn) as $financialTrxnParams) {
civicrm_api3('FinancialTrxn', 'create', $financialTrxnParams);
$trxnParams = array(
'total_amount' => $financialTrxnParams['total_amount'],
'contribution_id' => $this->_contributionID,
);
$contributionTotalAmount = CRM_Core_DAO::getFieldValue('CRM_Contribute_BAO_Contribution', $this->_contributionID, 'total_amount');
CRM_Contribute_BAO_Contribution::assignProportionalLineItems($trxnParams, $submittedValues['id'], $contributionTotalAmount);
}
}
else {
// simply update the financial trxn
civicrm_api3('FinancialTrxn', 'create', $submittedValues);
}
self::updateRelatedContribution($submittedValues, $this->_contributionID);
}
/**
* Wrapper for unit testing the post process submit function.
*
* @param array $params
*/
public function testSubmit($params) {
$this->_id = $params['id'];
$this->_contributionID = $params['contribution_id'];
$this->_values = civicrm_api3('FinancialTrxn', 'getsingle', array('id' => $params['id']));
$this->submit($params);
}
/**
* Function to update contribution's check_number and trxn_id by
* concatenating values from financial trxn's check_number and trxn_id respectively
*
* @param array $params
* @param int $contributionID
*/
public static function updateRelatedContribution($params, $contributionID) {
$contributionDAO = new CRM_Contribute_DAO_Contribution();
$contributionDAO->id = $contributionID;
$contributionDAO->find(TRUE);
foreach (array('trxn_id', 'check_number') as $fieldName) {
if (!empty($params[$fieldName])) {
if (!empty($contributionDAO->$fieldName)) {
$values = explode(',', $contributionDAO->$fieldName);
// if submitted check_number or trxn_id value is
// already present then ignore else add to $values array
if (!in_array($params[$fieldName], $values)) {
$values[] = $params[$fieldName];
}
$contributionDAO->$fieldName = implode(',', $values);
}
}
}
$contributionDAO->save();
}
/**
* Get payment fields
*/
public function getPaymentFields() {
$paymentFields = array(
'payment_instrument_id' => array(
'is_required' => TRUE,
'add_field' => TRUE,
),
'check_number' => array(
'is_required' => FALSE,
'add_field' => TRUE,
),
// @TODO we need to show card type icon in place of select field
'card_type_id' => array(
'is_required' => FALSE,
'add_field' => TRUE,
),
'pan_truncation' => array(
'is_required' => FALSE,
'add_field' => TRUE,
),
'trxn_id' => array(
'add_field' => TRUE,
'is_required' => FALSE,
),
'trxn_date' => array(
'htmlType' => 'datepicker',
'name' => 'trxn_date',
'title' => ts('Transaction Date'),
'is_required' => TRUE,
'attributes' => array(
'date' => 'yyyy-mm-dd',
'time' => 24,
),
),
'total_amount' => array(
'htmlType' => 'text',
'name' => 'total_amount',
'title' => ts('Total Amount'),
'is_required' => TRUE,
'attributes' => array(
'readonly' => TRUE,
'size' => 6,
),
),
);
return $paymentFields;
}
}