Merge pull request #227 from deepak-srivastava/crm
[civicrm-core.git] / api / v2 / PledgePayment.php
1 <?php
2 // $Id$
3
4 /*
5 +--------------------------------------------------------------------+
6 | CiviCRM version 4.3 |
7 +--------------------------------------------------------------------+
8 | Copyright CiviCRM LLC (c) 2004-2013 |
9 +--------------------------------------------------------------------+
10 | This file is a part of CiviCRM. |
11 | |
12 | CiviCRM is free software; you can copy, modify, and distribute it |
13 | under the terms of the GNU Affero General Public License |
14 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
15 | |
16 | CiviCRM is distributed in the hope that it will be useful, but |
17 | WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
19 | See the GNU Affero General Public License for more details. |
20 | |
21 | You should have received a copy of the GNU Affero General Public |
22 | License and the CiviCRM Licensing Exception along |
23 | with this program; if not, contact CiviCRM LLC |
24 | at info[AT]civicrm[DOT]org. If you have questions about the |
25 | GNU Affero General Public License or the licensing of CiviCRM, |
26 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
27 +--------------------------------------------------------------------+
28 */
29
30
31
32 /*
33 *DRAFT CODE WRITTEN BY EILEEN still dev version (pre-ALPHA)
34 *Starting point was Contribute API & some portions are still just that with
35 *contribute replaced by pledge & not yet tested
36 * have only been using create, delete functionality
37 */
38
39 /**
40 * File for the CiviCRM APIv2 Pledge functions
41 *
42 * @package CiviCRM_APIv2
43 * @subpackage API_Pledge_Payment
44 *
45 * @copyright CiviCRM LLC (c) 2004-2013
46 * @version $Id: PledgePayment.php
47 *
48 */
49
50 /**
51 * Include utility functions
52 */
53 require_once 'api/v2/utils.php';
54 require_once 'CRM/Utils/Rule.php';
55 function &civicrm_pledge_payment_add(&$params) {
56 $result = civicrm_pledge_create($params);
57 return $result;
58 }
59
60 /**
61 * Add or update a plege payment
62 *
63 * @param array $params (reference ) input parameters
64 *
65 * @return array (reference ) pledge_id of created or updated record
66 * @static void
67 * @access public
68 */
69 function &civicrm_pledge_payment_create(&$params) {
70 _civicrm_initialize();
71 //GAP - update doesn't recalculate payment dates on existing payment schedule - not the sure the code is in Civi to leverage
72 if (empty($params)) {
73 return civicrm_create_error(ts('No input parameters present'));
74 }
75
76 if (!is_array($params)) {
77 return civicrm_create_error(ts('Input parameters is not an array'));
78 }
79
80 $error = _civicrm_pledgepayment_check_params($params);
81 if (civicrm_error($error)) {
82 return $error;
83 }
84
85 $values = array();
86
87 require_once 'CRM/Pledge/BAO/PledgePayment.php';
88 $error = _civicrm_pledgepayment_format_params($params, $values);
89
90 if (civicrm_error($error)) {
91 return $error;
92 }
93
94 $pledge = CRM_Pledge_BAO_PledgePayment::getOldestPledgePayment($params['pledge_id']);
95 $params['id'] = $pledge['id'];
96
97 //params ID needs to be pledge payment ID
98 // pledge payment isn't retrieved if only one exists - the status is not set correctly causing this so let's get it for now as a cludgey make it work
99 // copied from getOldestPayment function
100 if (!$params['id']) {
101 $query = "
102 SELECT civicrm_pledge_payment.id id, civicrm_pledge_payment.scheduled_amount amount
103 FROM civicrm_pledge, civicrm_pledge_payment
104 WHERE civicrm_pledge.id = civicrm_pledge_payment.pledge_id
105 AND civicrm_pledge.id = %1
106 LIMIT 0, 1
107 ";
108 $params[1] = array($params['pledge_id'], 'Integer');
109 $payment = CRM_Core_DAO::executeQuery($query, $params);
110 $paymentDetails = NULL;
111 if ($payment->fetch()) {
112 $params['id'] = $payment->id;
113 }
114 }
115 CRM_Pledge_BAO_PledgePayment::add($params);
116
117 //update pledge status
118 CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($params['pledge_id']);
119 return $errors;
120 }
121
122 /**
123 * Retrieve a specific pledge, given a set of input params
124 * If more than one pledge exists, return an error, unless
125 * the client has requested to return the first found contact
126 *
127 * @param array $params (reference ) input parameters
128 *
129 * @return array (reference ) array of properties, if error an array with an error id and error message
130 * @static void
131 * @access public
132
133 function &civicrm_pledge_payment_get( &$params ) {
134 _civicrm_initialize( );
135 // copied from contribute code - not touched at all to make work for pledge or tested
136 $values = array( );
137 if ( empty( $params ) ) {
138 return civicrm_create_error( ts( 'No input parameters present' ) );
139 }
140
141 if ( ! is_array( $params ) ) {
142 return civicrm_create_error( ts( 'Input parameters is not an array' ) );
143 }
144
145 $pledges =& civicrm_pledge_search( $params );
146 if ( civicrm_error( $pledges ) ) {
147 return $pledges;
148 }
149
150 if ( count( $pledges ) != 1 &&
151 ! $params['returnFirst'] ) {
152 return civicrm_create_error( ts( '%1 pledges matching input params', array( 1 => count( $pledges ) ) ),
153 $pledges );
154 }
155
156 $payments = array_values( $pledges );
157 return $pledges[0];
158 }
159
160
161 /**
162 * Retrieve a set of pledges, given a set of input params
163 *
164 * @param array $params (reference ) input parameters
165 * @param array $returnProperties Which properties should be included in the
166 * returned pledge object. If NULL, the default
167 * set of properties will be included.
168 *
169 * @return array (reference ) array of pledges, if error an array with an error id and error message
170 * @static void
171 * @access public
172 */
173 function &civicrm_pledge_payment_search(&$params) {
174 _civicrm_initialize();
175 // copied from contribute code - not touched at all to make work for pledge or tested
176 if (!is_array($params)) {
177 return civicrm_create_error(ts('Input parameters is not an array'));
178 }
179
180 $inputParams = array();
181 $returnProperties = array();
182 $otherVars = array('sort', 'offset', 'rowCount');
183
184 $sort = NULL;
185 $offset = 0;
186 $rowCount = 25;
187 foreach ($params as $n => $v) {
188 if (substr($n, 0, 7) == 'return.') {
189 $returnProperties[substr($n, 7)] = $v;
190 }
191 elseif (in_array($n, $otherVars)) {
192 $$n = $v;
193 }
194 else {
195 $inputParams[$n] = $v;
196 }
197 }
198
199 // add is_test to the clause if not present
200 if (!array_key_exists('pledge_test', $inputParams)) {
201 $inputParams['pledge_test'] = 0;
202 }
203
204 require_once 'CRM/Pledge/BAO/Query.php';
205 require_once 'CRM/Contact/BAO/Query.php';
206 if (empty($returnProperties)) {
207 $returnProperties = CRM_Pledge_BAO_Query::defaultReturnProperties(CRM_Contact_BAO_Query::MODE_PLEDGE);
208 }
209
210 $newParams = CRM_Contact_BAO_Query::convertFormValues($inputParams);
211
212 $query = new CRM_Contact_BAO_Query($newParams, $returnProperties, NULL);
213 list($select, $from, $where) = $query->query();
214
215 $sql = "$select $from $where";
216
217 if (!empty($sort)) {
218 $sql .= " ORDER BY $sort ";
219 }
220 $sql .= " LIMIT $offset, $rowCount ";
221 $dao = CRM_Core_DAO::executeQuery($sql);
222
223 $pledge = array();
224 while ($dao->fetch()) {
225 $pledge[$dao->pledge_id] = $query->store($dao);
226 }
227 $dao->free();
228
229 return $pledge;
230 }
231
232 /**
233 *
234 * @param <type> $params
235 *
236 * @return <type>
237 */
238 function &civicrm_pledge_payment_format_create(&$params) {
239 _civicrm_initialize();
240
241 // return error if we have no params
242 if (empty($params)) {
243 return civicrm_create_error('Input Parameters empty');
244 }
245
246 $error = _civicrm_pledge_check_params($params);
247 if (civicrm_error($error)) {
248 return $error;
249 }
250 $values = array();
251 $error = _civicrm_pledge_format_params($params, $values);
252 if (civicrm_error($error)) {
253 return $error;
254 }
255
256 $error = _civicrm_pledge_duplicate_check($params);
257 if (civicrm_error($error)) {
258 return $error;
259 }
260 $ids = array();
261
262 CRM_Pledge_BAO_Pledge::resolveDefaults($params, TRUE);
263
264 $pledge = CRM_Pledge_BAO_Pledge::create($params, $ids);
265 _civicrm_object_to_array($pledge, $pledgeArray);
266 return $pledgeArray;
267 }
268
269 /**
270 * This function ensures that we have the right input pledge parameters
271 *
272 * We also need to make sure we run all the form rules on the params list
273 * to ensure that the params are valid
274 *
275 * @param array $params Associative array of property name/value
276 * pairs to insert in new pledge.
277 *
278 * @return bool|CRM_Utils_Error
279 * @access private
280 */
281 function _civicrm_pledgepayment_check_params(&$params) {
282 static $required = array(
283 'pledge_id',
284 );
285
286 // cannot create a pledge with empty params
287 if (empty($params)) {
288 return civicrm_create_error('Input Parameters empty');
289 }
290
291 $valid = TRUE;
292 $error = '';
293 foreach ($required as $field) {
294 if (!CRM_Utils_Array::value($field, $params)) {
295 $valid = FALSE;
296 $error .= $field;
297 break;
298 }
299 }
300
301 if (!$valid) {
302 return civicrm_create_error("Required fields not found for pledge $error");
303 }
304
305 return array();
306 }
307
308 /**
309 * Check if there is a pledge with the same trxn_id or invoice_id
310 *
311 * @param array $params Associative array of property name/value
312 * pairs to insert in new pledge.
313 *
314 * @return array|CRM_Error
315 * @access private
316 */
317
318
319 /* not yet looked at
320 * function _civicrm_pledge_duplicate_check( &$params ) {
321 require_once 'CRM/Pledge/BAO/Pledge.php';
322 $duplicates = array( );
323 $result = CRM_Pledge_BAO_Pledge::checkDuplicate( $params,$duplicates );
324 if ( $result ) {
325 $d = implode( ', ', $duplicates );
326 $error = CRM_Core_Error::createError( "Duplicate error - existing pledge record(s) have a matching Transaction ID or Invoice ID. pledge record ID(s) are: $d", CRM_Core_Error::DUPLICATE_pledge, 'Fatal', $d);
327 return civicrm_create_error( $error->pop( ),
328 $d );
329 } else {
330 return array();
331 }
332 }
333 */
334
335 /**
336 * take the input parameter list as specified in the data model and
337 * convert it into the same format that we use in QF and BAO object
338 *
339 * @param array $params Associative array of property name/value
340 * pairs to insert in new contact.
341 * @param array $values The reformatted properties that we can use internally
342 * '
343 *
344 * @return array|CRM_Error
345 * @access public
346 */
347 function _civicrm_pledgepayment_format_params(&$params, &$values, $create = FALSE) {
348 // copy all the pledge fields as is
349 require_once 'CRM/Pledge/BAO/PledgePayment.php';
350 require_once 'CRM/Pledge/DAO/Pledge.php';
351 $fields = CRM_Pledge_DAO_Pledge::fields();
352
353 _civicrm_store_values($fields, $params, $values);
354
355 foreach ($params as $key => $value) {
356 // ignore empty values or empty arrays etc
357 if (CRM_Utils_System::isNull($value)) {
358 continue;
359 }
360
361 switch ($key) {
362 case 'pledge_contact_id':
363 if (!CRM_Utils_Rule::integer($value)) {
364 return civicrm_create_error("contact_id not valid: $value");
365 }
366 $dao = new CRM_Core_DAO();
367 $qParams = array();
368 $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = $value",
369 $qParams
370 );
371 if (!$svq) {
372 return civicrm_create_error("Invalid Contact ID: There is no contact record with contact_id = $value.");
373 }
374
375 $values['contact_id'] = $values['pledge_contact_id'];
376 unset($values['pledge_contact_id']);
377 break;
378
379 case 'receive_date':
380 case 'end_date':
381 case 'pledge_create_date':
382 case 'cancel_date':
383 case 'receipt_date':
384 case 'thankyou_date':
385 if (!CRM_Utils_Rule::date($value)) {
386 return civicrm_create_error("$key not a valid date: $value");
387 }
388 break;
389
390 case 'non_deductible_amount':
391 case 'total_amount':
392 case 'fee_amount':
393 case 'net_amount':
394 if (!CRM_Utils_Rule::money($value)) {
395 return civicrm_create_error("$key not a valid amount: $value");
396 }
397 break;
398
399 case 'currency':
400 if (!CRM_Utils_Rule::currencyCode($value)) {
401 return civicrm_create_error("currency not a valid code: $value");
402 }
403 break;
404
405 case 'pledge_type':
406 $values['pledge_type_id'] = CRM_Utils_Array::key(ucfirst($value),
407 CRM_Pledge_PseudoConstant::pledgeType()
408 );
409 break;
410
411 case 'payment_instrument':
412 require_once 'CRM/Core/OptionGroup.php';
413 $values['payment_instrument_id'] = CRM_Core_OptionGroup::getValue('payment_instrument', $value);
414 break;
415
416 default:
417 break;
418 }
419 }
420
421 if (array_key_exists('note', $params)) {
422 $values['note'] = $params['note'];
423 }
424
425 if (array_key_exists('installment_amount', $params)) {
426 $values['installment_amount'] = $params['installment_amount'];
427 }
428 // testing testing - how do I make it take a create_date? It needs $values['create_date'] set but doesn't seem to like it because $fields calls it $pledge_create_date
429 //ditto scheduled date. I don't know why this is needs to be done because I don't fully understand the code above
430 if (array_key_exists('pledge_create_date', $params)) {
431 $values['create_date'] = $params['pledge_create_date'];
432 }
433 if (array_key_exists('pledge_scheduled_date', $params)) {
434 $values['scheduled_date'] = $params['pledge_scheduled_date'];
435 }
436 if (array_key_exists('pledge_create_date', $params)) {
437 $values['create_date'] = $params['pledge_create_date'];
438 }
439 if (array_key_exists('status_id', $params)) {
440 $values['status_id'] = $params['status_id'];
441 $values['pledge_status_id'] = $params['status_id'];
442 }
443
444 _civicrm_custom_format_params($params, $values, 'Pledge');
445
446 if ($create) {
447 // CRM_pledge_BAO_Pledge::add() handles Pledge_source
448 // So, if $values contains Pledge_source, convert it to source
449 $changes = array('pledge_source' => 'source');
450
451 foreach ($changes as $orgVal => $changeVal) {
452 if (isset($values[$orgVal])) {
453 $values[$changeVal] = $values[$orgVal];
454 unset($values[$orgVal]);
455 }
456 }
457 }
458
459 return array();
460 }
461
462
463 //having an 'interogate function to find what can be returned from an API would be SUPER useful. Ideally it would also advise which fields are required too. I
464 // imaging the most useful format would be to be like the $params array you need to pass in but the value for each field would be information about it. Ideally the
465 // function that sets which parameters are required would be accessible from this function to add them in
466 // function at the moment doesn't have custom fields
467 function civicrm_pledge_payment_interogate($params) {
468 $fields = CRM_Pledge_DAO_Pledge::fields();
469 $fields['installment_amount'] = array(
470 'name' => 'installment_amount',
471 'title' => ts('Installment Amount'),
472 );
473 unset($fields['amount']);
474 return $fields;
475 }
476
477 // this one should probably go in a pledge payment API
478 function updatePledgePayments($pledgeId, $paymentStatusId, $paymentIds) {
479 require_once 'CRM/Pledge/BAO/Pledge.php';
480 $result = updatePledgePayments($pledgeId, $paymentStatusId, $paymentIds = NULL);
481 return $result;
482 }
483