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