Merge pull request #11336 from eileenmcnaughton/live
[civicrm-core.git] / CRM / Batch / BAO / Batch.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
8c9251b3 6 | Copyright CiviCRM LLC (c) 2004-2018 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28/**
29 *
30 * @package CRM
8c9251b3 31 * @copyright CiviCRM LLC (c) 2004-2018
6a488035
TO
32 */
33
34/**
ce064e4f 35 * Batch BAO class.
6a488035
TO
36 */
37class CRM_Batch_BAO_Batch extends CRM_Batch_DAO_Batch {
38
39 /**
eceb18cc 40 * Cache for the current batch object.
6a488035
TO
41 */
42 static $_batch = NULL;
43
44 /**
45 * Not sure this is the best way to do this. Depends on how exportFinancialBatch() below gets called.
46 * Maybe a parameter to that function is better.
47 */
48 static $_exportFormat = NULL;
49
50 /**
eceb18cc 51 * Create a new batch.
6a488035 52 *
82d480a5 53 * @param array $params
6a488035 54 *
a6c01b45
CW
55 * @return object
56 * $batch batch object
6a488035 57 */
92e088c9 58 public static function create(&$params) {
debff434
PN
59 $op = 'edit';
60 $batchId = CRM_Utils_Array::value('id', $params);
61 if (!$batchId) {
62 $op = 'create';
6a488035
TO
63 $params['name'] = CRM_Utils_String::titleToVar($params['title']);
64 }
debff434 65 CRM_Utils_Hook::pre($op, 'Batch', $batchId, $params);
6a488035
TO
66 $batch = new CRM_Batch_DAO_Batch();
67 $batch->copyValues($params);
6a488035
TO
68 $batch->save();
69
debff434
PN
70 CRM_Utils_Hook::post($op, 'Batch', $batch->id, $batch);
71
6a488035
TO
72 return $batch;
73 }
74
75 /**
eceb18cc 76 * Retrieve the information about the batch.
6a488035 77 *
82d480a5
TO
78 * @param array $params
79 * (reference ) an assoc array of name/value pairs.
80 * @param array $defaults
81 * (reference ) an assoc array to hold the flattened values.
6a488035 82 *
a6c01b45
CW
83 * @return array
84 * CRM_Batch_BAO_Batch object on success, null otherwise
6a488035 85 */
00be9182 86 public static function retrieve(&$params, &$defaults) {
6a488035
TO
87 $batch = new CRM_Batch_DAO_Batch();
88 $batch->copyValues($params);
89 if ($batch->find(TRUE)) {
90 CRM_Core_DAO::storeValues($batch, $defaults);
91 return $batch;
92 }
93 return NULL;
94 }
95
96 /**
eceb18cc 97 * Get profile id associated with the batch type.
6a488035 98 *
82d480a5
TO
99 * @param int $batchTypeId
100 * Batch type id.
6a488035 101 *
a6c01b45
CW
102 * @return int
103 * $profileId profile id
6a488035 104 */
00be9182 105 public static function getProfileId($batchTypeId) {
6a488035
TO
106 //retrieve the profile specific to batch type
107 switch ($batchTypeId) {
108 case 1:
9fa00ed1 109 case 3:
110 //batch profile used for pledges
6a488035
TO
111 $profileName = "contribution_batch_entry";
112 break;
113
114 case 2:
115 //batch profile used for memberships
116 $profileName = "membership_batch_entry";
04e6444d 117 break;
6a488035
TO
118 }
119
120 // get and return the profile id
121 return CRM_Core_DAO::getFieldValue('CRM_Core_BAO_UFGroup', $profileName, 'id', 'name');
122 }
123
124 /**
eceb18cc 125 * Generate batch name.
6a488035 126 *
72b3a70c
CW
127 * @return string
128 * batch name
6a488035 129 */
00be9182 130 public static function generateBatchName() {
6a488035
TO
131 $sql = "SELECT max(id) FROM civicrm_batch";
132 $batchNo = CRM_Core_DAO::singleValueQuery($sql) + 1;
133 return ts('Batch %1', array(1 => $batchNo)) . ': ' . date('Y-m-d');
134 }
135
6a488035 136 /**
eceb18cc 137 * Delete batch entry.
6a488035 138 *
82d480a5
TO
139 * @param int $batchId
140 * Batch id.
6a488035 141 *
72b3a70c 142 * @return bool
6a488035 143 */
00be9182 144 public static function deleteBatch($batchId) {
6a488035 145 // delete entry from batch table
8f30d0b9 146 CRM_Utils_Hook::pre('delete', 'Batch', $batchId, CRM_Core_DAO::$_nullArray);
6a488035
TO
147 $batch = new CRM_Batch_DAO_Batch();
148 $batch->id = $batchId;
149 $batch->delete();
8f30d0b9 150 CRM_Utils_Hook::post('delete', 'Batch', $batch->id, $batch);
691df66d 151 return TRUE;
6a488035
TO
152 }
153
6a488035 154 /**
eceb18cc 155 * wrapper for ajax batch selector.
6a488035 156 *
82d480a5
TO
157 * @param array $params
158 * Associated array for params record id.
6a488035 159 *
a6c01b45
CW
160 * @return array
161 * associated array of batch list
6a488035 162 */
3fab79d8 163 public static function getBatchListSelector(&$params) {
6a488035
TO
164 // format the params
165 $params['offset'] = ($params['page'] - 1) * $params['rp'];
166 $params['rowCount'] = $params['rp'];
167 $params['sort'] = CRM_Utils_Array::value('sortBy', $params);
168
169 // get batches
170 $batches = self::getBatchList($params);
171
172 // get batch totals for open batches
173 $fetchTotals = array();
691df66d 174 $batchStatus = CRM_Core_PseudoConstant::get('CRM_Batch_DAO_Batch', 'status_id', array('labelColumn' => 'name'));
2d818e4a
PN
175 $batchStatus = array(
176 array_search('Open', $batchStatus),
177 array_search('Reopened', $batchStatus),
178 );
6a488035
TO
179 if ($params['context'] == 'financialBatch') {
180 foreach ($batches as $id => $batch) {
2d818e4a 181 if (in_array($batch['status_id'], $batchStatus)) {
6a488035
TO
182 $fetchTotals[] = $id;
183 }
184 }
185 }
186 $totals = self::batchTotals($fetchTotals);
187
188 // add count
189 $params['total'] = self::getBatchCount($params);
190
191 // format params and add links
192 $batchList = array();
193
194 foreach ($batches as $id => $value) {
195 $batch = array();
196 if ($params['context'] == 'financialBatch') {
197 $batch['check'] = $value['check'];
198 }
199 $batch['batch_name'] = $value['title'];
957bbb1d 200 $batch['total'] = '';
6a488035
TO
201 $batch['payment_instrument'] = $value['payment_instrument'];
202 $batch['item_count'] = CRM_Utils_Array::value('item_count', $value);
a46732f8 203 $batch['type'] = CRM_Utils_Array::value('batch_type', $value);
a7488080 204 if (!empty($value['total'])) {
def0f6ae
BS
205 // CRM-21205
206 $batch['total'] = CRM_Utils_Money::format($value['total'], $value['currency']);
6a488035
TO
207 }
208
209 // Compare totals with actuals
210 if (isset($totals[$id])) {
211 $batch['item_count'] = self::displayTotals($totals[$id]['item_count'], $batch['item_count']);
212 $batch['total'] = self::displayTotals(CRM_Utils_Money::format($totals[$id]['total']), $batch['total']);
213 }
214 $batch['status'] = $value['batch_status'];
215 $batch['created_by'] = $value['created_by'];
216 $batch['links'] = $value['action'];
217 $batchList[$id] = $batch;
218 }
219 return $batchList;
220 }
221
222 /**
eceb18cc 223 * Get list of batches.
6a488035 224 *
82d480a5
TO
225 * @param array $params
226 * Associated array for params.
102fe859
EM
227 *
228 * @return array
6a488035 229 */
00be9182 230 public static function getBatchList(&$params) {
857236d0 231 $apiParams = self::whereClause($params);
6a488035
TO
232
233 if (!empty($params['rowCount']) && is_numeric($params['rowCount'])
234 && is_numeric($params['offset']) && $params['rowCount'] > 0
235 ) {
857236d0 236 $apiParams['options'] = array('offset' => $params['offset'], 'limit' => $params['rowCount']);
6a488035 237 }
857236d0 238 $apiParams['options']['sort'] = 'id DESC';
6a488035 239 if (!empty($params['sort'])) {
857236d0 240 $apiParams['options']['sort'] = CRM_Utils_Type::escape($params['sort'], 'String');
6a488035
TO
241 }
242
857236d0
PN
243 $return = array(
244 "id",
245 "name",
246 "title",
247 "description",
248 "created_date",
249 "status_id",
250 "modified_id",
251 "modified_date",
252 "type_id",
253 "mode_id",
254 "total",
255 "item_count",
256 "exported_date",
257 "payment_instrument_id",
258 "created_id.sort_name",
259 "created_id",
260 );
261 $apiParams['return'] = $return;
262 $batches = civicrm_api3('Batch', 'get', $apiParams);
3fab79d8 263 $obj = new CRM_Batch_BAO_Batch();
a7488080 264 if (!empty($params['context'])) {
3fab79d8 265 $links = $obj->links($params['context']);
6a488035
TO
266 }
267 else {
3fab79d8 268 $links = $obj->links();
6a488035
TO
269 }
270
97afa853
AS
271 $batchTypes = CRM_Core_PseudoConstant::get('CRM_Batch_DAO_Batch', 'type_id');
272 $batchStatus = CRM_Core_PseudoConstant::get('CRM_Batch_DAO_Batch', 'status_id');
2d818e4a 273 $batchStatusByName = CRM_Core_PseudoConstant::get('CRM_Batch_DAO_Batch', 'status_id', array('labelColumn' => 'name'));
6a488035
TO
274 $paymentInstrument = CRM_Contribute_PseudoConstant::paymentInstrument();
275
276 $results = array();
857236d0 277 foreach ($batches['values'] as $values) {
6a488035 278 $newLinks = $links;
6a488035
TO
279 $action = array_sum(array_keys($newLinks));
280
2d818e4a 281 if ($values['status_id'] == array_search('Closed', $batchStatusByName) && $params['context'] != 'financialBatch') {
6a488035
TO
282 $newLinks = array();
283 }
284 elseif ($params['context'] == 'financialBatch') {
6c552737 285 $values['check'] = "<input type='checkbox' id='check_" .
857236d0 286 $values['id'] .
0b0941e2 287 "' name='check_" .
857236d0 288 $values['id'] .
0b0941e2 289 "' value='1' data-status_id='" .
92fcb95f 290 $values['status_id'] . "' class='select-row'></input>";
6a488035 291
2d818e4a
PN
292 switch ($batchStatusByName[$values['status_id']]) {
293 case 'Open':
ca0e2dda 294 case 'Reopened':
6a488035
TO
295 CRM_Utils_Array::remove($newLinks, 'reopen', 'download');
296 break;
691df66d 297
2d818e4a 298 case 'Closed':
6a488035
TO
299 CRM_Utils_Array::remove($newLinks, 'close', 'edit', 'download');
300 break;
691df66d 301
2d818e4a 302 case 'Exported':
6a488035
TO
303 CRM_Utils_Array::remove($newLinks, 'close', 'edit', 'reopen', 'export');
304 }
ca0e2dda 305 if (!CRM_Batch_BAO_Batch::checkBatchPermission('edit', $values['created_id'])) {
f07fc4c9
PN
306 CRM_Utils_Array::remove($newLinks, 'edit');
307 }
308 if (!CRM_Batch_BAO_Batch::checkBatchPermission('close', $values['created_id'])) {
309 CRM_Utils_Array::remove($newLinks, 'close', 'export');
310 }
311 if (!CRM_Batch_BAO_Batch::checkBatchPermission('reopen', $values['created_id'])) {
312 CRM_Utils_Array::remove($newLinks, 'reopen');
ca0e2dda
PN
313 }
314 if (!CRM_Batch_BAO_Batch::checkBatchPermission('export', $values['created_id'])) {
315 CRM_Utils_Array::remove($newLinks, 'export', 'download');
316 }
317 if (!CRM_Batch_BAO_Batch::checkBatchPermission('delete', $values['created_id'])) {
318 CRM_Utils_Array::remove($newLinks, 'delete');
319 }
6a488035 320 }
a7488080 321 if (!empty($values['type_id'])) {
6a488035
TO
322 $values['batch_type'] = $batchTypes[$values['type_id']];
323 }
324 $values['batch_status'] = $batchStatus[$values['status_id']];
857236d0 325 $values['created_by'] = $values['created_id.sort_name'];
6a488035 326 $values['payment_instrument'] = '';
857236d0
PN
327 if (!empty($values['payment_instrument_id'])) {
328 $values['payment_instrument'] = $paymentInstrument[$values['payment_instrument_id']];
6a488035 329 }
857236d0 330 $tokens = array('id' => $values['id'], 'status' => $values['status_id']);
2d818e4a 331 if ($values['status_id'] == array_search('Exported', $batchStatusByName)) {
857236d0
PN
332 $aid = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Export Accounting Batch');
333 $activityParams = array('source_record_id' => $values['id'], 'activity_type_id' => $aid);
6a488035 334 $exportActivity = CRM_Activity_BAO_Activity::retrieve($activityParams, $val);
0b0941e2 335 $fid = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_EntityFile', $exportActivity->id, 'file_id', 'entity_id');
6a488035
TO
336 $tokens = array_merge(array('eid' => $exportActivity->id, 'fid' => $fid), $tokens);
337 }
338 $values['action'] = CRM_Core_Action::formLink(
339 $newLinks,
340 $action,
c51d1602 341 $tokens,
87dab4a4
AH
342 ts('more'),
343 FALSE,
344 'batch.selector.row',
345 'Batch',
857236d0 346 $values['id']
6a488035 347 );
def0f6ae
BS
348 // CRM-21205
349 $values['currency'] = CRM_Core_DAO::singleValueQuery("
350 SELECT GROUP_CONCAT(DISTINCT ft.currency)
351 FROM civicrm_batch batch
352 JOIN civicrm_entity_batch eb
353 ON batch.id = eb.batch_id
354 JOIN civicrm_financial_trxn ft
355 ON eb.entity_id = ft.id
356 WHERE batch.id = %1
357 GROUP BY batch.id
358 ", array(1 => array($values['id'], 'Positive')));
857236d0 359 $results[$values['id']] = $values;
6a488035
TO
360 }
361
362 return $results;
363 }
364
365 /**
eceb18cc 366 * Get count of batches.
6a488035 367 *
82d480a5
TO
368 * @param array $params
369 * Associated array for params.
102fe859
EM
370 *
371 * @return null|string
6a488035 372 */
b11c92be 373 public static function getBatchCount(&$params) {
857236d0
PN
374 $apiParams = self::whereClause($params);
375 return civicrm_api3('Batch', 'getCount', $apiParams);
6a488035
TO
376 }
377
378 /**
eceb18cc 379 * Format where clause for getting lists of batches.
6a488035 380 *
82d480a5
TO
381 * @param array $params
382 * Associated array for params.
102fe859
EM
383 *
384 * @return string
6a488035 385 */
b11c92be 386 public static function whereClause($params) {
6a488035
TO
387 $clauses = array();
388 // Exclude data-entry batches
2d818e4a 389 $batchStatus = CRM_Core_PseudoConstant::get('CRM_Batch_DAO_Batch', 'status_id', array('labelColumn' => 'name'));
6a488035 390 if (empty($params['status_id'])) {
857236d0 391 $clauses['status_id'] = array('NOT IN' => array("Data Entry"));
6a488035
TO
392 }
393
857236d0
PN
394 $return = array(
395 "id",
396 "name",
397 "title",
398 "description",
399 "created_date",
400 "status_id",
401 "modified_id",
402 "modified_date",
403 "type_id",
404 "mode_id",
405 "total",
406 "item_count",
407 "exported_date",
408 "payment_instrument_id",
409 "created_id.sort_name",
410 "created_id",
6a488035 411 );
d2738983
PN
412 if (!CRM_Core_Permission::check("view all manual batches")) {
413 if (CRM_Core_Permission::check("view own manual batches")) {
414 $loggedInContactId = CRM_Core_Session::singleton()->get('userID');
415 $params['created_id'] = $loggedInContactId;
416 }
417 else {
418 $params['created_id'] = 0;
419 }
420 }
857236d0
PN
421 foreach ($return as $field) {
422 if (!isset($params[$field])) {
423 continue;
424 }
425 $value = CRM_Utils_Type::escape($params[$field], 'String', FALSE);
426 if (in_array($field, array('name', 'title', 'description', 'created_id.sort_name'))) {
427 $clauses[$field] = array('LIKE' => "%{$value}%");
428 }
429 elseif ($field == 'status_id' && $value == array_search('Open', $batchStatus)) {
430 $clauses['status_id'] = array('IN' => array("Open", 'Reopened'));
431 }
432 else {
433 $clauses[$field] = $value;
6a488035
TO
434 }
435 }
857236d0 436 return $clauses;
6a488035
TO
437 }
438
439 /**
eceb18cc 440 * Define action links.
6a488035 441 *
102fe859
EM
442 * @param null $context
443 *
a6c01b45
CW
444 * @return array
445 * array of action links
6a488035 446 */
00be9182 447 public function links($context = NULL) {
6a488035
TO
448 if ($context == 'financialBatch') {
449 $links = array(
691df66d 450 'transaction' => array(
353ffa53
TO
451 'name' => ts('Transactions'),
452 'url' => 'civicrm/batchtransaction',
453 'qs' => 'reset=1&bid=%%id%%',
6a488035
TO
454 'title' => ts('View/Add Transactions to Batch'),
455 ),
691df66d 456 'edit' => array(
353ffa53
TO
457 'name' => ts('Edit'),
458 'url' => 'civicrm/financial/batch',
459 'qs' => 'reset=1&action=update&id=%%id%%&context=1',
6a488035
TO
460 'title' => ts('Edit Batch'),
461 ),
691df66d 462 'close' => array(
353ffa53 463 'name' => ts('Close'),
6a488035 464 'title' => ts('Close Batch'),
353ffa53 465 'url' => '#',
6a488035
TO
466 'extra' => 'rel="close"',
467 ),
691df66d 468 'export' => array(
353ffa53 469 'name' => ts('Export'),
6a488035 470 'title' => ts('Export Batch'),
353ffa53 471 'url' => '#',
6a488035
TO
472 'extra' => 'rel="export"',
473 ),
691df66d 474 'reopen' => array(
353ffa53 475 'name' => ts('Re-open'),
6a488035 476 'title' => ts('Re-open Batch'),
353ffa53 477 'url' => '#',
6a488035
TO
478 'extra' => 'rel="reopen"',
479 ),
691df66d 480 'delete' => array(
353ffa53 481 'name' => ts('Delete'),
6a488035 482 'title' => ts('Delete Batch'),
353ffa53 483 'url' => '#',
6a488035
TO
484 'extra' => 'rel="delete"',
485 ),
486 'download' => array(
353ffa53
TO
487 'name' => ts('Download'),
488 'url' => 'civicrm/file',
489 'qs' => 'reset=1&id=%%fid%%&eid=%%eid%%',
6a488035 490 'title' => ts('Download Batch'),
21dfd5f5 491 ),
6a488035
TO
492 );
493 }
494 else {
495 $links = array(
496 CRM_Core_Action::COPY => array(
497 'name' => ts('Enter records'),
498 'url' => 'civicrm/batch/entry',
499 'qs' => 'id=%%id%%&reset=1',
500 'title' => ts('Batch Data Entry'),
501 ),
502 CRM_Core_Action::UPDATE => array(
503 'name' => ts('Edit'),
504 'url' => 'civicrm/batch',
505 'qs' => 'action=update&id=%%id%%&reset=1',
506 'title' => ts('Edit Batch'),
507 ),
508 CRM_Core_Action::DELETE => array(
509 'name' => ts('Delete'),
510 'url' => 'civicrm/batch',
511 'qs' => 'action=delete&id=%%id%%',
512 'title' => ts('Delete Batch'),
21dfd5f5 513 ),
6a488035
TO
514 );
515 }
516 return $links;
517 }
518
519 /**
eceb18cc 520 * Get batch list.
6a488035 521 *
a6c01b45 522 * @return array
72b3a70c 523 * all batches excluding batches with data entry in progress
6a488035 524 */
00be9182 525 public static function getBatches() {
a28ce73f 526 $dataEntryStatusId = CRM_Core_PseudoConstant::getKey('CRM_Batch_BAO_Batch', 'status_id', 'Data Entry');
acb4ca2f 527 $query = "SELECT id, title
6a488035 528 FROM civicrm_batch
acb4ca2f
DG
529 WHERE item_count >= 1
530 AND status_id != {$dataEntryStatusId}
433465bc 531 ORDER BY title";
6a488035
TO
532
533 $batches = array();
534 $dao = CRM_Core_DAO::executeQuery($query);
481a74f4 535 while ($dao->fetch()) {
6a488035
TO
536 $batches[$dao->id] = $dao->title;
537 }
538 return $batches;
539 }
540
541
6a488035 542 /**
eceb18cc 543 * Calculate sum of all entries in a batch.
6a488035
TO
544 * Used to validate and update item_count and total when closing an accounting batch
545 *
546 * @param array $batchIds
547 * @return array
548 */
00be9182 549 public static function batchTotals($batchIds) {
6a488035
TO
550 $totals = array_fill_keys($batchIds, array('item_count' => 0, 'total' => 0));
551 if ($batchIds) {
552 $sql = "SELECT eb.batch_id, COUNT(tx.id) AS item_count, SUM(tx.total_amount) AS total
553 FROM civicrm_entity_batch eb
554 INNER JOIN civicrm_financial_trxn tx ON tx.id = eb.entity_id AND eb.entity_table = 'civicrm_financial_trxn'
555 WHERE eb.batch_id IN (" . implode(',', $batchIds) . ")
556 GROUP BY eb.batch_id";
557 $dao = CRM_Core_DAO::executeQuery($sql);
558 while ($dao->fetch()) {
559 $totals[$dao->batch_id] = (array) $dao;
560 }
561 $dao->free();
562 }
563 return $totals;
564 }
565
566 /**
eceb18cc 567 * Format markup for comparing two totals.
6a488035 568 *
72b3a70c
CW
569 * @param $actual
570 * calculated total
571 * @param $expected
572 * user-entered total
6a488035
TO
573 * @return array
574 */
00be9182 575 public static function displayTotals($actual, $expected) {
6a488035
TO
576 $class = 'actual-value';
577 if ($expected && $expected != $actual) {
578 $class .= ' crm-error';
579 }
580 $actualTitle = ts('Current Total');
581 $output = "<span class='$class' title='$actualTitle'>$actual</span>";
582 if ($expected) {
583 $expectedTitle = ts('Expected Total');
584 $output .= " / <span class='expected-value' title='$expectedTitle'>$expected</span>";
585 }
586 return $output;
587 }
588
589 /**
590 * Function for exporting financial accounts, currently we support CSV and IIF format
591 * @see http://wiki.civicrm.org/confluence/display/CRM/CiviAccounts+Specifications+-++Batches#CiviAccountsSpecifications-Batches-%C2%A0Overviewofimplementation
592 *
82d480a5
TO
593 * @param array $batchIds
594 * Associated array of batch ids.
595 * @param string $exportFormat
596 * Export format.
f3d529fc
PN
597 * @param bool $downloadFile
598 * Download export file?.
6a488035 599 */
f3d529fc 600 public static function exportFinancialBatch($batchIds, $exportFormat, $downloadFile) {
6a488035
TO
601 if (empty($batchIds)) {
602 CRM_Core_Error::fatal(ts('No batches were selected.'));
603 return;
604 }
605 if (empty($exportFormat)) {
606 CRM_Core_Error::fatal(ts('No export format selected.'));
607 return;
608 }
609 self::$_exportFormat = $exportFormat;
610
611 // Instantiate appropriate exporter based on user-selected format.
612 $exporterClass = "CRM_Financial_BAO_ExportFormat_" . self::$_exportFormat;
481a74f4 613 if (class_exists($exporterClass)) {
6a488035
TO
614 $exporter = new $exporterClass();
615 }
616 else {
617 CRM_Core_Error::fatal("Could not locate exporter: $exporterClass");
618 }
f091b037 619 $export = array();
f3d529fc 620 $exporter->_isDownloadFile = $downloadFile;
9b05de29 621 foreach ($batchIds as $batchId) {
f091b037
PN
622 // export only batches whose status is set to Exported.
623 $result = civicrm_api3('Batch', 'getcount', array(
624 'id' => $batchId,
625 'status_id' => "Exported",
626 ));
627 if (!$result) {
628 continue;
629 }
9b05de29 630 $export[$batchId] = $exporter->generateExportQuery($batchId);
6a488035 631 }
f091b037
PN
632 if ($export) {
633 $exporter->makeExport($export);
634 }
6a488035
TO
635 }
636
e0ef6999
EM
637 /**
638 * @param array $batchIds
639 * @param $status
640 */
00be9182 641 public static function closeReOpen($batchIds = array(), $status) {
f0ebbc90 642 $batchStatus = CRM_Core_PseudoConstant::get('CRM_Batch_DAO_Batch', 'status_id');
481a74f4
TO
643 $params['status_id'] = CRM_Utils_Array::key($status, $batchStatus);
644 $session = CRM_Core_Session::singleton();
6a488035 645 $params['modified_date'] = date('YmdHis');
481a74f4 646 $params['modified_id'] = $session->get('userID');
6a488035
TO
647 foreach ($batchIds as $key => $value) {
648 $params['id'] = $ids['batchID'] = $value;
649 self::create($params, $ids);
650 }
691df66d 651 $url = CRM_Utils_System::url('civicrm/financial/financialbatches', "reset=1&batchStatus={$params['status_id']}");
6a488035
TO
652 CRM_Utils_System::redirect($url);
653 }
654
655 /**
eceb18cc 656 * Retrieve financial items assigned for a batch.
6a488035
TO
657 *
658 * @param int $entityID
659 * @param array $returnValues
72b3a70c 660 * @param bool $notPresent
100fef9d 661 * @param array $params
102fe859
EM
662 * @param bool $getCount
663 *
72b3a70c 664 * @return CRM_Core_DAO
6a488035 665 */
00be9182 666 public static function getBatchFinancialItems($entityID, $returnValues, $notPresent = NULL, $params = NULL, $getCount = FALSE) {
6a488035
TO
667 if (!$getCount) {
668 if (!empty($params['rowCount']) &&
669 $params['rowCount'] > 0
670 ) {
671 $limit = " LIMIT {$params['offset']}, {$params['rowCount']} ";
672 }
673 }
674 // action is taken depending upon the mode
675 $select = 'civicrm_financial_trxn.id ';
481a74f4 676 if (!empty($returnValues)) {
92fcb95f 677 $select .= " , " . implode(' , ', $returnValues);
6a488035
TO
678 }
679
680 $orderBy = " ORDER BY civicrm_financial_trxn.id";
21d32567
DL
681 if (!empty($params['sort'])) {
682 $orderBy = ' ORDER BY ' . CRM_Utils_Type::escape($params['sort'], 'String');
6a488035
TO
683 }
684
685 $from = "civicrm_financial_trxn
c4b067f6
PN
686INNER JOIN civicrm_entity_financial_trxn ON civicrm_entity_financial_trxn.financial_trxn_id = civicrm_financial_trxn.id
687INNER JOIN civicrm_contribution ON (civicrm_contribution.id = civicrm_entity_financial_trxn.entity_id
688 AND civicrm_entity_financial_trxn.entity_table='civicrm_contribution')
cc55c603
DG
689LEFT JOIN civicrm_entity_batch ON civicrm_entity_batch.entity_table = 'civicrm_financial_trxn'
690AND civicrm_entity_batch.entity_id = civicrm_financial_trxn.id
6a488035
TO
691LEFT JOIN civicrm_financial_type ON civicrm_financial_type.id = civicrm_contribution.financial_type_id
692LEFT JOIN civicrm_contact contact_a ON contact_a.id = civicrm_contribution.contact_id
693LEFT JOIN civicrm_contribution_soft ON civicrm_contribution_soft.contribution_id = civicrm_contribution.id
694";
695
6c552737
TO
696 $searchFields = array(
697 'sort_name',
698 'financial_type_id',
699 'contribution_page_id',
30d46f2f 700 'payment_instrument_id',
701 'contribution_trxn_id',
6c552737
TO
702 'contribution_source',
703 'contribution_currency_type',
704 'contribution_pay_later',
705 'contribution_recurring',
706 'contribution_test',
707 'contribution_thankyou_date_is_not_null',
708 'contribution_receipt_date_is_not_null',
709 'contribution_pcp_made_through_id',
710 'contribution_pcp_display_in_roll',
711 'contribution_date_relative',
712 'contribution_amount_low',
713 'contribution_amount_high',
714 'contribution_in_honor_of',
715 'contact_tags',
716 'group',
717 'contribution_date_relative',
718 'contribution_date_high',
719 'contribution_date_low',
720 'contribution_check_number',
721 'contribution_status_id',
722 );
6a488035
TO
723 $values = array();
724 foreach ($searchFields as $field) {
725 if (isset($params[$field])) {
726 $values[$field] = $params[$field];
727 if ($field == 'sort_name') {
728 $from .= " LEFT JOIN civicrm_contact contact_b ON contact_b.id = civicrm_contribution.contact_id
729 LEFT JOIN civicrm_email ON contact_b.id = civicrm_email.contact_id";
730 }
731 if ($field == 'contribution_in_honor_of') {
732 $from .= " LEFT JOIN civicrm_contact contact_b ON contact_b.id = civicrm_contribution.contact_id";
733 }
734 if ($field == 'contact_tags') {
735 $from .= " LEFT JOIN civicrm_entity_tag `civicrm_entity_tag-{$params[$field]}` ON `civicrm_entity_tag-{$params[$field]}`.entity_id = contact_a.id";
736 }
737 if ($field == 'group') {
738 $from .= " LEFT JOIN civicrm_group_contact `civicrm_group_contact-{$params[$field]}` ON contact_a.id = `civicrm_group_contact-{$params[$field]}`.contact_id ";
739 }
740 if ($field == 'contribution_date_relative') {
741 $relativeDate = explode('.', $params[$field]);
742 $date = CRM_Utils_Date::relativeToAbsolute($relativeDate[0], $relativeDate[1]);
743 $values['contribution_date_low'] = $date['from'];
744 $values['contribution_date_high'] = $date['to'];
745 }
746 $searchParams = CRM_Contact_BAO_Query::convertFormValues($values);
8f165fa5 747 // @todo the use of defaultReturnProperties means the search will be inefficient
748 // as slow-unneeded properties are included.
6a488035
TO
749 $query = new CRM_Contact_BAO_Query($searchParams,
750 CRM_Contribute_BAO_Query::defaultReturnProperties(CRM_Contact_BAO_Query::MODE_CONTRIBUTE,
751 FALSE
691df66d 752 ), NULL, FALSE, FALSE, CRM_Contact_BAO_Query::MODE_CONTRIBUTE
6a488035
TO
753 );
754 if ($field == 'contribution_date_high' || $field == 'contribution_date_low') {
755 $query->dateQueryBuilder($params[$field], 'civicrm_contribution', 'contribution_date', 'receive_date', 'Contribution Date');
756 }
757 }
758 }
759 if (!empty($query->_where[0])) {
0b0941e2 760 $where = implode(' AND ', $query->_where[0]) .
c4b067f6 761 " AND civicrm_entity_batch.batch_id IS NULL ";
30d46f2f 762 $where = str_replace('civicrm_contribution.payment_instrument_id', 'civicrm_financial_trxn.payment_instrument_id', $where);
6a488035
TO
763 }
764 else {
6a488035 765 if (!$notPresent) {
c4b067f6 766 $where = " civicrm_entity_batch.batch_id = {$entityID} ";
6a488035
TO
767 }
768 else {
c4b067f6 769 $where = " civicrm_entity_batch.batch_id IS NULL ";
6a488035
TO
770 }
771 }
772
0b0941e2
DL
773 $sql = "
774SELECT {$select}
775FROM {$from}
776WHERE {$where}
777 {$orderBy}
6a488035
TO
778";
779
780 if (isset($limit)) {
781 $sql .= "{$limit}";
782 }
783
784 $result = CRM_Core_DAO::executeQuery($sql);
785 return $result;
786 }
787
788 /**
eceb18cc 789 * Get batch names.
6a488035
TO
790 * @param string $batchIds
791 *
a6c01b45
CW
792 * @return array
793 * array of batches
6a488035 794 */
00be9182 795 public static function getBatchNames($batchIds) {
6a488035
TO
796 $query = 'SELECT id, title
797 FROM civicrm_batch
86bfa4f6 798 WHERE id IN (' . $batchIds . ')';
6a488035
TO
799
800 $batches = array();
801 $dao = CRM_Core_DAO::executeQuery($query);
481a74f4 802 while ($dao->fetch()) {
6a488035
TO
803 $batches[$dao->id] = $dao->title;
804 }
805 return $batches;
806 }
807
808 /**
eceb18cc 809 * Function get batch statuses.
6a488035
TO
810 *
811 * @param string $batchIds
812 *
a6c01b45
CW
813 * @return array
814 * array of batches
6a488035 815 */
00be9182 816 public static function getBatchStatuses($batchIds) {
6a488035
TO
817 $query = 'SELECT id, status_id
818 FROM civicrm_batch
92fcb95f 819 WHERE id IN (' . $batchIds . ')';
6a488035
TO
820
821 $batches = array();
822 $dao = CRM_Core_DAO::executeQuery($query);
481a74f4 823 while ($dao->fetch()) {
6a488035
TO
824 $batches[$dao->id] = $dao->status_id;
825 }
826 return $batches;
827 }
96025800 828
ca0e2dda
PN
829 /**
830 * Function to check permission for batch.
831 *
832 * @param string $action
833 * @param int $batchCreatedId
834 * batch created by contact id
835 *
836 * @return bool
837 */
838 public static function checkBatchPermission($action, $batchCreatedId = NULL) {
ca0e2dda
PN
839 if (CRM_Core_Permission::check("{$action} all manual batches")) {
840 return TRUE;
841 }
842 if (CRM_Core_Permission::check("{$action} own manual batches")) {
843 $loggedInContactId = CRM_Core_Session::singleton()->get('userID');
844 if ($batchCreatedId == $loggedInContactId) {
845 return TRUE;
846 }
847 elseif (CRM_Utils_System::isNull($batchCreatedId)) {
848 return TRUE;
849 }
850 }
851 return FALSE;
852 }
853
6a488035 854}