Merge pull request #19334 from civicrm/5.33
[civicrm-core.git] / CRM / Financial / Form / PaymentEdit.php
CommitLineData
9b2e3ee6
MD
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
9b2e3ee6 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9b2e3ee6
MD
9 +--------------------------------------------------------------------+
10 */
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
9b2e3ee6
MD
16 */
17class CRM_Financial_Form_PaymentEdit extends CRM_Core_Form {
18
19 /**
20 * The id of the financial trxn.
21 *
22 * @var int
23 */
24 protected $_id;
25
e3a78cba 26 /**
27 * The id of the related contribution ID
28 *
29 * @var int
30 */
31 protected $_contributionID;
32
9b2e3ee6
MD
33 /**
34 * The variable which holds the information of a financial transaction
35 *
36 * @var array
37 */
38 protected $_values;
39
d8c01ab5 40 /**
41 * Explicitly declare the form context.
42 */
43 public function getDefaultContext() {
44 return 'create';
45 }
7b966967 46
9b2e3ee6
MD
47 /**
48 * Set variables up before form is built.
49 */
50 public function preProcess() {
d8c01ab5 51 $this->_action = CRM_Core_Action::UPDATE;
9b2e3ee6
MD
52 parent::preProcess();
53 $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
54 $this->assign('id', $this->_id);
50f8ceb1 55 $this->_contributionID = CRM_Utils_Request::retrieve('contribution_id', 'Positive', $this);
9b2e3ee6 56
be2fb01f 57 $this->_values = civicrm_api3('FinancialTrxn', 'getsingle', ['id' => $this->_id]);
9b2e3ee6 58 if (!empty($this->_values['payment_processor_id'])) {
c485e792 59 CRM_Core_Error::statusBounce(ts('You cannot update this payment as it is tied to a payment processor'));
9b2e3ee6
MD
60 }
61 }
62
63 /**
64 * Set default values.
65 *
66 * @return array
67 */
68 public function setDefaultValues() {
77ea7225 69 $defaults = $this->_values;
7030792a 70 $defaults['total_amount'] = CRM_Utils_Money::formatLocaleNumericRoundedForDefaultCurrency($this->_values['total_amount']);
77ea7225 71 return $defaults;
9b2e3ee6
MD
72 }
73
74 /**
75 * Build quickForm.
76 */
77 public function buildQuickForm() {
78 CRM_Utils_System::setTitle(ts('Update Payment details'));
79
80 $paymentFields = $this->getPaymentFields();
81 $this->assign('paymentFields', $paymentFields);
82 foreach ($paymentFields as $name => $paymentField) {
4ee75265 83 if (!empty($paymentField['add_field'])) {
be2fb01f 84 $attributes = [
a7a8f17d 85 'entity' => 'FinancialTrxn',
86 'name' => $name,
be2fb01f 87 ];
a7a8f17d 88 $this->addField($name, $attributes, $paymentField['is_required']);
4ee75265 89 }
90 else {
91 $this->add($paymentField['htmlType'],
92 $name,
93 $paymentField['title'],
94 $paymentField['attributes'],
95 $paymentField['is_required']
96 );
9b2e3ee6
MD
97 }
98 }
99
100 $this->assign('currency', CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_Currency', $this->_values['currency'], 'symbol', 'name'));
be2fb01f 101 $this->addFormRule([__CLASS__, 'formRule'], $this);
4ee75265 102
be2fb01f
CW
103 $this->addButtons([
104 [
9b2e3ee6
MD
105 'type' => 'submit',
106 'name' => ts('Update'),
107 'isDefault' => TRUE,
be2fb01f
CW
108 ],
109 [
9b2e3ee6
MD
110 'type' => 'cancel',
111 'name' => ts('Cancel'),
be2fb01f
CW
112 ],
113 ]);
9b2e3ee6
MD
114 }
115
4ee75265 116 /**
117 * Global form rule.
118 *
119 * @param array $fields
120 * The input form values.
121 * @param array $files
122 * The uploaded files if any.
123 * @param $self
124 *
125 * @return bool|array
126 * true if no errors, else array of errors
127 */
128 public static function formRule($fields, $files, $self) {
be2fb01f 129 $errors = [];
4ee75265 130
131 // if Credit Card is chosen and pan_truncation is not NULL ensure that it's value is numeric else throw validation error
132 if (CRM_Core_PseudoConstant::getName('CRM_Financial_DAO_FinancialTrxn', 'payment_instrument_id', $fields['payment_instrument_id']) == 'Credit Card' &&
133 !empty($fields['pan_truncation']) &&
134 !CRM_Utils_Rule::numeric($fields['pan_truncation'])
135 ) {
136 $errors['pan_truncation'] = ts('Please enter a valid Card Number');
137 }
138
139 return $errors;
140 }
141
9b2e3ee6
MD
142 /**
143 * Process the form submission.
144 */
145 public function postProcess() {
be2fb01f 146 $params = [
9b2e3ee6 147 'id' => $this->_id,
4ee75265 148 'payment_instrument_id' => $this->_submitValues['payment_instrument_id'],
6b409353 149 'trxn_id' => $this->_submitValues['trxn_id'] ?? NULL,
9b2e3ee6 150 'trxn_date' => CRM_Utils_Array::value('trxn_date', $this->_submitValues, date('YmdHis')),
be2fb01f 151 ];
4ee75265 152
153 $paymentInstrumentName = CRM_Core_PseudoConstant::getName('CRM_Financial_DAO_FinancialTrxn', 'payment_instrument_id', $params['payment_instrument_id']);
154 if ($paymentInstrumentName == 'Credit Card') {
9c1bc317
CW
155 $params['card_type_id'] = $this->_submitValues['card_type_id'] ?? NULL;
156 $params['pan_truncation'] = $this->_submitValues['pan_truncation'] ?? NULL;
4ee75265 157 }
158 elseif ($paymentInstrumentName == 'Check') {
9c1bc317 159 $params['check_number'] = $this->_submitValues['check_number'] ?? NULL;
9b2e3ee6 160 }
4ee75265 161
e3a78cba 162 $this->submit($params);
163
501ec37c
CW
164 $contactId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->_contributionID, 'contact_id');
165 $url = CRM_Utils_System::url(
166 "civicrm/contact/view/contribution",
167 "reset=1&action=update&id={$this->_contributionID}&cid={$contactId}&context=contribution"
168 );
169 CRM_Core_Session::singleton()->pushUserContext($url);
e3a78cba 170 }
171
e3a78cba 172 /**
173 * Wrapper function to process form submission
174 *
175 * @param array $submittedValues
176 *
d8a1b674 177 * @throws \CiviCRM_API3_Exception
e3a78cba 178 */
179 protected function submit($submittedValues) {
180 // if payment instrument is changed then
181 // 1. Record a new reverse financial transaction with old payment instrument
182 // 2. Record a new financial transaction with new payment instrument
183 // 3. Add EntityFinancialTrxn records to relate with corresponding financial item and contribution
184 if ($submittedValues['payment_instrument_id'] != $this->_values['payment_instrument_id']) {
d8a1b674 185 civicrm_api3('Payment', 'cancel', [
186 'id' => $this->_values['id'],
187 'trxn_date' => $submittedValues['trxn_date'],
188 ]);
a9dec23a 189
d8a1b674 190 $newFinancialTrxn = $submittedValues;
191 unset($newFinancialTrxn['id']);
e3a78cba 192 $newFinancialTrxn['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($submittedValues['payment_instrument_id']);
d8a1b674 193 $newFinancialTrxn['total_amount'] = $this->_values['total_amount'];
194 $newFinancialTrxn['currency'] = $this->_values['currency'];
195 civicrm_api3('Payment', 'create', $newFinancialTrxn);
a9dec23a 196 }
197 else {
198 // simply update the financial trxn
e3a78cba 199 civicrm_api3('FinancialTrxn', 'create', $submittedValues);
a9dec23a 200 }
650b79b4 201
fdd77f88 202 CRM_Financial_BAO_Payment::updateRelatedContribution($submittedValues, $this->_contributionID);
9b2e3ee6
MD
203 }
204
a9dec23a 205 /**
e3a78cba 206 * Wrapper for unit testing the post process submit function.
a9dec23a 207 *
e3a78cba 208 * @param array $params
d8a1b674 209 *
210 * @throws \CiviCRM_API3_Exception
a9dec23a 211 */
d8a1b674 212 public function testSubmit(array $params): void {
e3a78cba 213 $this->_id = $params['id'];
214 $this->_contributionID = $params['contribution_id'];
be2fb01f 215 $this->_values = civicrm_api3('FinancialTrxn', 'getsingle', ['id' => $params['id']]);
e3a78cba 216
217 $this->submit($params);
a9dec23a 218 }
219
9b2e3ee6
MD
220 /**
221 * Get payment fields
222 */
223 public function getPaymentFields() {
be2fb01f
CW
224 $paymentFields = [
225 'payment_instrument_id' => [
4ee75265 226 'is_required' => TRUE,
227 'add_field' => TRUE,
be2fb01f
CW
228 ],
229 'check_number' => [
9b2e3ee6 230 'is_required' => FALSE,
4ee75265 231 'add_field' => TRUE,
be2fb01f 232 ],
4ee75265 233 // @TODO we need to show card type icon in place of select field
be2fb01f 234 'card_type_id' => [
4ee75265 235 'is_required' => FALSE,
236 'add_field' => TRUE,
be2fb01f
CW
237 ],
238 'pan_truncation' => [
4ee75265 239 'is_required' => FALSE,
240 'add_field' => TRUE,
be2fb01f
CW
241 ],
242 'trxn_id' => [
a7a8f17d 243 'add_field' => TRUE,
4ee75265 244 'is_required' => FALSE,
be2fb01f
CW
245 ],
246 'trxn_date' => [
9b2e3ee6
MD
247 'htmlType' => 'datepicker',
248 'name' => 'trxn_date',
249 'title' => ts('Transaction Date'),
4ee75265 250 'is_required' => TRUE,
be2fb01f 251 'attributes' => [
9b2e3ee6
MD
252 'date' => 'yyyy-mm-dd',
253 'time' => 24,
be2fb01f
CW
254 ],
255 ],
256 'total_amount' => [
9b2e3ee6
MD
257 'htmlType' => 'text',
258 'name' => 'total_amount',
259 'title' => ts('Total Amount'),
4ee75265 260 'is_required' => TRUE,
be2fb01f 261 'attributes' => [
9b2e3ee6
MD
262 'readonly' => TRUE,
263 'size' => 6,
be2fb01f
CW
264 ],
265 ],
266 ];
9b2e3ee6
MD
267
268 return $paymentFields;
269 }
270
271}