Merge pull request #11965 from colemanw/CRM-21855
[civicrm-core.git] / tests / phpunit / api / v3 / ReportTemplateTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
81621fee 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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035 27
6a488035
TO
28/**
29 * Test APIv3 civicrm_report_instance_* functions
30 *
6c6e6187
TO
31 * @package CiviCRM_APIv3
32 * @subpackage API_Report
acb109b7 33 * @group headless
6a488035 34 */
6a488035 35class api_v3_ReportTemplateTest extends CiviUnitTestCase {
e2779f6e 36 protected $_apiversion = 3;
b7c9bc4c 37
2c6b4783 38 /**
39 * Our group reports use an alter so transaction cleanup won't work.
40 *
41 * @throws \Exception
42 */
43 public function tearDown() {
44 $this->quickCleanUpFinancialEntities();
0626851e 45 $this->quickCleanup(array('civicrm_group', 'civicrm_saved_search', 'civicrm_group_contact', 'civicrm_group_contact_cache', 'civicrm_group'));
2c6b4783 46 parent::tearDown();
6a488035
TO
47 }
48
6a488035 49 public function testReportTemplate() {
7fbb4198 50 $result = $this->callAPISuccess('ReportTemplate', 'create', array(
6a488035
TO
51 'label' => 'Example Form',
52 'description' => 'Longish description of the example form',
53 'class_name' => 'CRM_Report_Form_Examplez',
54 'report_url' => 'example/path',
55 'component' => 'CiviCase',
56 ));
1cbea43e 57 $this->assertAPISuccess($result);
ba4a1892 58 $this->assertEquals(1, $result['count']);
6a488035 59 $entityId = $result['id'];
ba4a1892
TM
60 $this->assertTrue(is_numeric($entityId));
61 $this->assertEquals(7, $result['values'][$entityId]['component_id']);
6a488035
TO
62 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value
63 WHERE name = "CRM_Report_Form_Examplez"
0201b57f 64 AND option_group_id IN (SELECT id from civicrm_option_group WHERE name = "report_template") ');
6a488035
TO
65 $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_option_value
66 WHERE name = "CRM_Report_Form_Examplez"');
67
68 // change component to null
6c6e6187 69 $result = $this->callAPISuccess('ReportTemplate', 'create', array(
92915c55 70 'id' => $entityId,
6a488035
TO
71 'component' => '',
72 ));
1cbea43e 73 $this->assertAPISuccess($result);
ba4a1892 74 $this->assertEquals(1, $result['count']);
6a488035
TO
75 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value
76 WHERE name = "CRM_Report_Form_Examplez"
0201b57f 77 AND option_group_id IN (SELECT id from civicrm_option_group WHERE name = "report_template") ');
6a488035
TO
78 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value
79 WHERE name = "CRM_Report_Form_Examplez"
80 AND component_id IS NULL');
81
82 // deactivate
6c6e6187 83 $result = $this->callAPISuccess('ReportTemplate', 'create', array(
92915c55 84 'id' => $entityId,
6a488035
TO
85 'is_active' => 0,
86 ));
1cbea43e 87 $this->assertAPISuccess($result);
ba4a1892 88 $this->assertEquals(1, $result['count']);
6a488035
TO
89 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value
90 WHERE name = "CRM_Report_Form_Examplez"
0201b57f 91 AND option_group_id IN (SELECT id from civicrm_option_group WHERE name = "report_template") ');
6a488035
TO
92 $this->assertDBQuery(0, 'SELECT is_active FROM civicrm_option_value
93 WHERE name = "CRM_Report_Form_Examplez"');
94
95 // activate
6c6e6187 96 $result = $this->callAPISuccess('ReportTemplate', 'create', array(
92915c55 97 'id' => $entityId,
6a488035
TO
98 'is_active' => 1,
99 ));
1cbea43e 100 $this->assertAPISuccess($result);
ba4a1892 101 $this->assertEquals(1, $result['count']);
6a488035
TO
102 $this->assertDBQuery(1, 'SELECT count(*) FROM civicrm_option_value
103 WHERE name = "CRM_Report_Form_Examplez"
0201b57f 104 AND option_group_id IN (SELECT id from civicrm_option_group WHERE name = "report_template") ');
6a488035
TO
105 $this->assertDBQuery(1, 'SELECT is_active FROM civicrm_option_value
106 WHERE name = "CRM_Report_Form_Examplez"');
107
92915c55
TO
108 $result = $this->callAPISuccess('ReportTemplate', 'delete', array(
109 'id' => $entityId,
6a488035 110 ));
1cbea43e 111 $this->assertAPISuccess($result);
ba4a1892 112 $this->assertEquals(1, $result['count']);
6a488035
TO
113 $this->assertDBQuery(0, 'SELECT count(*) FROM civicrm_option_value
114 WHERE name = "CRM_Report_Form_Examplez"
115 ');
116 }
e2779f6e
E
117
118 /**
fe482240 119 * Test getrows on contact summary report.
e2779f6e 120 */
00be9182 121 public function testReportTemplateGetRowsContactSummary() {
5c49fee0 122 $description = "Retrieve rows from a report template (optionally providing the instance_id).";
fee15d2a 123 $result = $this->callAPIAndDocument('report_template', 'getrows', array(
e2779f6e 124 'report_id' => 'contact/summary',
21dfd5f5 125 'options' => array('metadata' => array('labels', 'title')),
0626851e 126 ), __FUNCTION__, __FILE__, $description, 'Getrows');
781d91c8 127 $this->assertEquals('Contact Name', $result['metadata']['labels']['civicrm_contact_sort_name']);
e2779f6e
E
128
129 //the second part of this test has been commented out because it relied on the db being reset to
130 // it's base state
131 //wasn't able to get that to work consistently
132 // however, when the db is in the base state the tests do pass
133 // and because the test covers 'all' contacts we can't create our own & assume the others don't exist
134 /*
135 $this->assertEquals(2, $result['count']);
136 $this->assertEquals('Default Organization', $result[0]['civicrm_contact_sort_name']);
137 $this->assertEquals('Second Domain', $result[1]['civicrm_contact_sort_name']);
138 $this->assertEquals('15 Main St', $result[1]['civicrm_address_street_address']);
e70a7fc0 139 */
e2779f6e
E
140 }
141
142 /**
fe482240
EM
143 * Tet api to get rows from reports.
144 *
e2779f6e 145 * @dataProvider getReportTemplates
fe482240 146 *
1e1fdcf6 147 * @param $reportID
fe482240 148 *
1e1fdcf6 149 * @throws \PHPUnit_Framework_IncompleteTestError
e2779f6e 150 */
00be9182 151 public function testReportTemplateGetRowsAllReports($reportID) {
22e263ad 152 if (stristr($reportID, 'has existing issues')) {
e2779f6e
E
153 $this->markTestIncomplete($reportID);
154 }
fe482240 155 $this->callAPISuccess('report_template', 'getrows', array(
92915c55 156 'report_id' => $reportID,
e2779f6e
E
157 ));
158 }
159
160 /**
fe482240
EM
161 * Test get statistics.
162 *
e2779f6e 163 * @dataProvider getReportTemplates
fe482240 164 *
1e1fdcf6 165 * @param $reportID
fe482240 166 *
1e1fdcf6 167 * @throws \PHPUnit_Framework_IncompleteTestError
e2779f6e 168 */
00be9182 169 public function testReportTemplateGetStatisticsAllReports($reportID) {
22e263ad 170 if (stristr($reportID, 'has existing issues')) {
e2779f6e
E
171 $this->markTestIncomplete($reportID);
172 }
22e263ad 173 if (in_array($reportID, array('contribute/softcredit', 'contribute/bookkeeping'))) {
e2779f6e
E
174 $this->markTestIncomplete($reportID . " has non enotices when calling statistics fn");
175 }
5c49fee0 176 $description = "Get Statistics from a report (note there isn't much data to get in the test DB).";
fee15d2a 177 $result = $this->callAPIAndDocument('report_template', 'getstatistics', array(
e2779f6e 178 'report_id' => $reportID,
fee15d2a 179 ), __FUNCTION__, __FILE__, $description, 'Getstatistics', 'getstatistics');
e2779f6e
E
180 }
181
182 /**
fe482240
EM
183 * Data provider function for getting all templates.
184 *
185 * Note that the function needs to
e2779f6e
E
186 * be static so cannot use $this->callAPISuccess
187 */
188 public static function getReportTemplates() {
189 $reportsToSkip = array(
92915c55 190 'activity' => 'does not respect function signature on from clause',
92915c55 191 'event/income' => 'I do no understand why but error is Call to undefined method CRM_Report_Form_Event_Income::from() in CRM/Report/Form.php on line 2120',
92915c55 192 'logging/contact/summary' => '(likely to be test related) probably logging off Undefined index: Form/Contact/LoggingSummary.php(231): PHP',
92915c55 193 'logging/contribute/summary' => '(likely to be test related) probably logging off DB Error: no such table',
92915c55 194 'contribute/history' => 'Declaration of CRM_Report_Form_Contribute_History::buildRows() should be compatible with CRM_Report_Form::buildRows($sql, &$rows)',
cb5aba81 195 'activitySummary' => 'We use temp tables for the main query generation and name are dynamic. These names are not available in stats() when called directly.',
e2779f6e
E
196 );
197
198 $reports = civicrm_api3('report_template', 'get', array('return' => 'value', 'options' => array('limit' => 500)));
199 foreach ($reports['values'] as $report) {
22e263ad 200 if (empty($reportsToSkip[$report['value']])) {
e2779f6e
E
201 $reportTemplates[] = array($report['value']);
202 }
203 else {
86bfa4f6 204 $reportTemplates[] = array($report['value'] . " has existing issues : " . $reportsToSkip[$report['value']]);
e2779f6e
E
205 }
206 }
207
e2779f6e
E
208 return $reportTemplates;
209 }
96025800 210
2c6b4783 211 /**
212 * Get contribution templates that work with basic filter tests.
213 *
214 * These templates require minimal data config.
215 */
216 public static function getContributionReportTemplates() {
eae0f0d9 217 return array(array('contribute/summary'), array('contribute/detail'), array('contribute/repeat'), array('topDonor' => 'contribute/topDonor'));
218 }
219
220 /**
221 * Get contribution templates that work with basic filter tests.
222 *
223 * These templates require minimal data config.
224 */
225 public static function getMembershipReportTemplates() {
226 return array(array('member/detail'));
227 }
228
229 public static function getMembershipAndContributionReportTemplatesForGroupTests() {
230 $templates = array_merge(self::getContributionReportTemplates(), self::getMembershipReportTemplates());
231 foreach ($templates as $key => $value) {
232 if (array_key_exists('topDonor', $value)) {
233 // Report is not standard enough to test here.
234 unset($templates[$key]);
235 }
236
237 }
238 return $templates;
2c6b4783 239 }
240
c160fde8 241 /**
242 * Test Lybunt report to check basic inclusion of a contact who gave in the year before the chosen year.
243 */
244 public function testLybuntReportWithData() {
245 $inInd = $this->individualCreate();
246 $outInd = $this->individualCreate();
247 $this->contributionCreate(array('contact_id' => $inInd, 'receive_date' => '2014-03-01'));
248 $this->contributionCreate(array('contact_id' => $outInd, 'receive_date' => '2015-03-01', 'trxn_id' => NULL, 'invoice_id' => NULL));
249 $rows = $this->callAPISuccess('report_template', 'getrows', array(
250 'report_id' => 'contribute/lybunt',
251 'yid_value' => 2015,
252 'yid_op' => 'calendar',
253 'options' => array('metadata' => array('sql')),
254 ));
255 $this->assertEquals(1, $rows['count'], "Report failed - the sql used to generate the results was " . print_r($rows['metadata']['sql'], TRUE));
256 }
257
33072bc7 258 /**
259 * Test Lybunt report applies ACLs.
260 */
261 public function testLybuntReportWithDataAndACLFilter() {
262 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('administer CiviCRM');
263 $inInd = $this->individualCreate();
264 $outInd = $this->individualCreate();
265 $this->contributionCreate(array('contact_id' => $inInd, 'receive_date' => '2014-03-01'));
266 $this->contributionCreate(array('contact_id' => $outInd, 'receive_date' => '2015-03-01', 'trxn_id' => NULL, 'invoice_id' => NULL));
267 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookNoResults'));
268 $params = array(
269 'report_id' => 'contribute/lybunt',
270 'yid_value' => 2015,
271 'yid_op' => 'calendar',
272 'options' => array('metadata' => array('sql')),
273 'check_permissions' => 1,
274 );
275
276 $rows = $this->callAPISuccess('report_template', 'getrows', $params);
277 $this->assertEquals(0, $rows['count'], "Report failed - the sql used to generate the results was " . print_r($rows['metadata']['sql'], TRUE));
278
279 CRM_Utils_Hook::singleton()->reset();
280 }
281
c160fde8 282 /**
283 * Test Lybunt report to check basic inclusion of a contact who gave in the year before the chosen year.
284 */
285 public function testLybuntReportWithFYData() {
286 $inInd = $this->individualCreate();
287 $outInd = $this->individualCreate();
288 $this->contributionCreate(array('contact_id' => $inInd, 'receive_date' => '2014-10-01'));
289 $this->contributionCreate(array('contact_id' => $outInd, 'receive_date' => '2015-03-01', 'trxn_id' => NULL, 'invoice_id' => NULL));
290 $this->callAPISuccess('Setting', 'create', array('fiscalYearStart' => array('M' => 7, 'd' => 1)));
291 $rows = $this->callAPISuccess('report_template', 'getrows', array(
292 'report_id' => 'contribute/lybunt',
293 'yid_value' => 2015,
294 'yid_op' => 'fiscal',
295 'options' => array('metadata' => array('sql')),
296 'order_bys' => array(
297 array(
298 'column' => 'first_name',
299 'order' => 'ASC',
300 ),
301 ),
302 ));
303
304 $this->assertEquals(2, $rows['count'], "Report failed - the sql used to generate the results was " . print_r($rows['metadata']['sql'], TRUE));
15d9e604 305
306 $this->assertContains('DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
307 SELECT SQL_CALC_FOUND_ROWS contact_civireport.id as cid FROM civicrm_contact contact_civireport INNER JOIN civicrm_contribution contribution_civireport USE index (received_date) ON contribution_civireport.contact_id = contact_civireport.id
308 AND contribution_civireport.is_test = 0
309 AND contribution_civireport.receive_date BETWEEN \'20140701000000\' AND \'20150630235959\'
310
311 LEFT JOIN civicrm_contribution cont_exclude ON cont_exclude.contact_id = contact_civireport.id
312 AND cont_exclude.receive_date BETWEEN \'2015-7-1\' AND \'20160630235959\' WHERE cont_exclude.id IS NULL AND 1 AND ( contribution_civireport.contribution_status_id IN (1) )
313 GROUP BY contact_civireport.id', $rows['metadata']['sql'][0]);
c160fde8 314 }
315
3fd9a92a 316 /**
317 * Test Lybunt report to check basic inclusion of a contact who gave in the year before the chosen year.
318 */
319 public function testLybuntReportWithFYDataOrderByLastYearAmount() {
320 $inInd = $this->individualCreate();
321 $outInd = $this->individualCreate();
322 $this->contributionCreate(array('contact_id' => $inInd, 'receive_date' => '2014-10-01'));
323 $this->contributionCreate(array('contact_id' => $outInd, 'receive_date' => '2015-03-01', 'trxn_id' => NULL, 'invoice_id' => NULL));
324 $this->callAPISuccess('Setting', 'create', array('fiscalYearStart' => array('M' => 7, 'd' => 1)));
325 $rows = $this->callAPISuccess('report_template', 'getrows', array(
326 'report_id' => 'contribute/lybunt',
327 'yid_value' => 2015,
328 'yid_op' => 'fiscal',
329 'options' => array('metadata' => array('sql')),
330 'fields' => array('first_name'),
331 'order_bys' => array(
332 array(
333 'column' => 'last_year_total_amount',
334 'order' => 'ASC',
335 ),
336 ),
337 ));
338
339 $this->assertEquals(2, $rows['count'], "Report failed - the sql used to generate the results was " . print_r($rows['metadata']['sql'], TRUE));
340 }
341
2c6b4783 342 /**
343 * Test the group filter works on the contribution summary (with a smart group).
eae0f0d9 344 *
345 * @dataProvider getMembershipAndContributionReportTemplatesForGroupTests
346 *
347 * @param string $template
348 * Name of the template to test.
2c6b4783 349 */
eae0f0d9 350 public function testContributionSummaryWithSmartGroupFilter($template) {
2c6b4783 351 $groupID = $this->setUpPopulatedSmartGroup();
352 $rows = $this->callAPISuccess('report_template', 'getrows', array(
eae0f0d9 353 'report_id' => $template,
2c6b4783 354 'gid_value' => $groupID,
355 'gid_op' => 'in',
356 'options' => array('metadata' => array('sql')),
357 ));
eae0f0d9 358 $this->assertNumberOfContactsInResult(3, $rows, $template);
359 if ($template === 'contribute/summary') {
360 $this->assertEquals(3, $rows['values'][0]['civicrm_contribution_total_amount_count']);
361 }
2c6b4783 362 }
363
364 /**
eae0f0d9 365 * Test the group filter works on the contribution summary.
366 *
367 * @dataProvider getMembershipAndContributionReportTemplatesForGroupTests
2c6b4783 368 */
eae0f0d9 369 public function testContributionSummaryWithNotINSmartGroupFilter($template) {
2c6b4783 370 $groupID = $this->setUpPopulatedSmartGroup();
371 $rows = $this->callAPISuccess('report_template', 'getrows', array(
372 'report_id' => 'contribute/summary',
373 'gid_value' => $groupID,
43c1fa19 374 'gid_op' => 'notin',
2c6b4783 375 'options' => array('metadata' => array('sql')),
376 ));
377 $this->assertEquals(2, $rows['values'][0]['civicrm_contribution_total_amount_count']);
378
379 }
380
381 /**
eae0f0d9 382 * Test the group filter works on the various reports.
2c6b4783 383 *
eae0f0d9 384 * @dataProvider getMembershipAndContributionReportTemplatesForGroupTests
2c6b4783 385 *
386 * @param string $template
387 * Report template unique identifier.
388 */
eae0f0d9 389 public function testReportsWithNonSmartGroupFilter($template) {
2c6b4783 390 $groupID = $this->setUpPopulatedGroup();
391 $rows = $this->callAPISuccess('report_template', 'getrows', array(
392 'report_id' => $template,
393 'gid_value' => array($groupID),
394 'gid_op' => 'in',
395 'options' => array('metadata' => array('sql')),
396 ));
397 $this->assertNumberOfContactsInResult(1, $rows, $template);
398 }
399
400 /**
401 * Assert the included results match the expected.
402 *
403 * There may or may not be a group by in play so the assertion varies a little.
404 *
405 * @param int $numberExpected
406 * @param array $rows
407 * Rows returned from the report.
408 * @param string $template
409 */
410 protected function assertNumberOfContactsInResult($numberExpected, $rows, $template) {
411 if (isset($rows['values'][0]['civicrm_contribution_total_amount_count'])) {
412 $this->assertEquals($numberExpected, $rows['values'][0]['civicrm_contribution_total_amount_count'], 'wrong row count in ' . $template);
413 }
414 else {
415 $this->assertEquals($numberExpected, count($rows['values']), 'wrong row count in ' . $template);
416 }
417 }
418
419 /**
420 * Test the group filter works on the contribution summary when 2 groups are involved.
421 */
422 public function testContributionSummaryWithTwoGroups() {
423 $groupID = $this->setUpPopulatedGroup();
424 $groupID2 = $this->setUpPopulatedSmartGroup();
425 $rows = $this->callAPISuccess('report_template', 'getrows', array(
426 'report_id' => 'contribute/summary',
427 'gid_value' => array($groupID, $groupID2),
428 'gid_op' => 'in',
429 'options' => array('metadata' => array('sql')),
430 ));
431 $this->assertEquals(4, $rows['values'][0]['civicrm_contribution_total_amount_count']);
432 }
433
27367f58 434 /**
435 * CRM-20640: Test the group filter works on the contribution summary when a single contact in 2 groups.
436 */
437 public function testContributionSummaryWithSingleContactsInTwoGroups() {
438 list($groupID1, $individualID) = $this->setUpPopulatedGroup(TRUE);
439 // create second group and add the individual to it.
440 $groupID2 = $this->groupCreate(array('name' => uniqid(), 'title' => uniqid()));
441 $this->callAPISuccess('GroupContact', 'create', array(
442 'group_id' => $groupID2,
443 'contact_id' => $individualID,
444 'status' => 'Added',
445 ));
446
447 $rows = $this->callAPISuccess('report_template', 'getrows', array(
448 'report_id' => 'contribute/summary',
449 'gid_value' => array($groupID1, $groupID2),
450 'gid_op' => 'in',
451 'options' => array('metadata' => array('sql')),
452 ));
453 $this->assertEquals(1, $rows['count']);
454 }
455
2c6b4783 456 /**
457 * Test the group filter works on the contribution summary when 2 groups are involved.
458 */
459 public function testContributionSummaryWithTwoGroupsWithIntersection() {
460 $groups = $this->setUpIntersectingGroups();
461
462 $rows = $this->callAPISuccess('report_template', 'getrows', array(
463 'report_id' => 'contribute/summary',
464 'gid_value' => $groups,
465 'gid_op' => 'in',
466 'options' => array('metadata' => array('sql')),
467 ));
468 $this->assertEquals(7, $rows['values'][0]['civicrm_contribution_total_amount_count']);
469 }
470
471 /**
472 * Set up a smart group for testing.
473 *
474 * The smart group includes all Households by filter. In addition an individual
475 * is created and hard-added and an individual is created that is not added.
476 *
477 * One household is hard-added as well as being in the filter.
478 *
479 * This gives us a range of scenarios for testing contacts are included only once
480 * whenever they are hard-added or in the criteria.
481 *
482 * @return int
483 */
484 public function setUpPopulatedSmartGroup() {
485 $household1ID = $this->householdCreate();
486 $individual1ID = $this->individualCreate();
487 $householdID = $this->householdCreate();
488 $individualID = $this->individualCreate();
489 $individualIDRemoved = $this->individualCreate();
490 $groupID = $this->smartGroupCreate(array(), array('name' => uniqid(), 'title' => uniqid()));
491 $this->callAPISuccess('GroupContact', 'create', array(
492 'group_id' => $groupID,
493 'contact_id' => $individualIDRemoved,
494 'status' => 'Removed',
495 ));
496 $this->callAPISuccess('GroupContact', 'create', array(
497 'group_id' => $groupID,
498 'contact_id' => $individualID,
499 'status' => 'Added',
500 ));
501 $this->callAPISuccess('GroupContact', 'create', array(
502 'group_id' => $groupID,
503 'contact_id' => $householdID,
504 'status' => 'Added',
505 ));
506 foreach (array($household1ID, $individual1ID, $householdID, $individualID, $individualIDRemoved) as $contactID) {
507 $this->contributionCreate(array('contact_id' => $contactID, 'invoice_id' => '', 'trxn_id' => ''));
eae0f0d9 508 $this->contactMembershipCreate(array('contact_id' => $contactID));
2c6b4783 509 }
510
511 // Refresh the cache for test purposes. It would be better to alter to alter the GroupContact add function to add contacts to the cache.
0626851e 512 CRM_Contact_BAO_GroupContactCache::clearGroupContactCache($groupID);
2c6b4783 513 return $groupID;
514 }
515
516 /**
eae0f0d9 517 * Set up a static group for testing.
2c6b4783 518 *
eae0f0d9 519 * An individual is created and hard-added and an individual is created that is not added.
2c6b4783 520 *
521 * This gives us a range of scenarios for testing contacts are included only once
522 * whenever they are hard-added or in the criteria.
523 *
27367f58 524 * @param bool $returnAddedContact
525 *
2c6b4783 526 * @return int
527 */
27367f58 528 public function setUpPopulatedGroup($returnAddedContact = FALSE) {
2c6b4783 529 $individual1ID = $this->individualCreate();
530 $individualID = $this->individualCreate();
531 $individualIDRemoved = $this->individualCreate();
532 $groupID = $this->groupCreate(array('name' => uniqid(), 'title' => uniqid()));
533 $this->callAPISuccess('GroupContact', 'create', array(
534 'group_id' => $groupID,
535 'contact_id' => $individualIDRemoved,
536 'status' => 'Removed',
537 ));
538 $this->callAPISuccess('GroupContact', 'create', array(
539 'group_id' => $groupID,
540 'contact_id' => $individualID,
541 'status' => 'Added',
542 ));
543
544 foreach (array($individual1ID, $individualID, $individualIDRemoved) as $contactID) {
545 $this->contributionCreate(array('contact_id' => $contactID, 'invoice_id' => '', 'trxn_id' => ''));
eae0f0d9 546 $this->contactMembershipCreate(array('contact_id' => $contactID));
2c6b4783 547 }
548
549 // Refresh the cache for test purposes. It would be better to alter to alter the GroupContact add function to add contacts to the cache.
0626851e 550 CRM_Contact_BAO_GroupContactCache::clearGroupContactCache($groupID);
27367f58 551
552 if ($returnAddedContact) {
553 return array($groupID, $individualID);
554 }
555
2c6b4783 556 return $groupID;
557 }
558
559 /**
560 * @return array
561 */
562 public function setUpIntersectingGroups() {
563 $groupID = $this->setUpPopulatedGroup();
564 $groupID2 = $this->setUpPopulatedSmartGroup();
565 $addedToBothIndividualID = $this->individualCreate();
566 $removedFromBothIndividualID = $this->individualCreate();
567 $addedToSmartGroupRemovedFromOtherIndividualID = $this->individualCreate();
568 $removedFromSmartGroupAddedToOtherIndividualID = $this->individualCreate();
569 $this->callAPISuccess('GroupContact', 'create', array(
570 'group_id' => $groupID,
571 'contact_id' => $addedToBothIndividualID,
572 'status' => 'Added',
573 ));
574 $this->callAPISuccess('GroupContact', 'create', array(
575 'group_id' => $groupID2,
576 'contact_id' => $addedToBothIndividualID,
577 'status' => 'Added',
578 ));
579 $this->callAPISuccess('GroupContact', 'create', array(
580 'group_id' => $groupID,
581 'contact_id' => $removedFromBothIndividualID,
582 'status' => 'Removed',
583 ));
584 $this->callAPISuccess('GroupContact', 'create', array(
585 'group_id' => $groupID2,
586 'contact_id' => $removedFromBothIndividualID,
587 'status' => 'Removed',
588 ));
589 $this->callAPISuccess('GroupContact', 'create', array(
590 'group_id' => $groupID2,
591 'contact_id' => $addedToSmartGroupRemovedFromOtherIndividualID,
592 'status' => 'Added',
593 ));
594 $this->callAPISuccess('GroupContact', 'create', array(
595 'group_id' => $groupID,
596 'contact_id' => $addedToSmartGroupRemovedFromOtherIndividualID,
597 'status' => 'Removed',
598 ));
599 $this->callAPISuccess('GroupContact', 'create', array(
600 'group_id' => $groupID,
601 'contact_id' => $removedFromSmartGroupAddedToOtherIndividualID,
602 'status' => 'Added',
603 ));
604 $this->callAPISuccess('GroupContact', 'create', array(
605 'group_id' => $groupID2,
606 'contact_id' => $removedFromSmartGroupAddedToOtherIndividualID,
607 'status' => 'Removed',
608 ));
609
610 foreach (array(
611 $addedToBothIndividualID,
612 $removedFromBothIndividualID,
613 $addedToSmartGroupRemovedFromOtherIndividualID,
614 $removedFromSmartGroupAddedToOtherIndividualID,
615 ) as $contactID) {
616 $this->contributionCreate(array(
617 'contact_id' => $contactID,
618 'invoice_id' => '',
619 'trxn_id' => '',
620 ));
621 }
622 return array($groupID, $groupID2);
623 }
624
45f8590c
PN
625 /**
626 * Test Deferred Revenue Report.
627 */
628 public function testDeferredRevenueReport() {
629 $indv1 = $this->individualCreate();
630 $indv2 = $this->individualCreate();
631 $params = array(
632 'contribution_invoice_settings' => array(
633 'deferred_revenue_enabled' => '1',
634 ),
635 );
636 $this->callAPISuccess('Setting', 'create', $params);
637 $this->contributionCreate(
638 array(
639 'contact_id' => $indv1,
640 'receive_date' => '2016-10-01',
641 'revenue_recognition_date' => date('Y-m-t', strtotime(date('ymd') . '+3 month')),
642 'financial_type_id' => 2,
643 )
644 );
645 $this->contributionCreate(
646 array(
647 'contact_id' => $indv1,
648 'revenue_recognition_date' => date('Y-m-t', strtotime(date('ymd') . '+22 month')),
649 'financial_type_id' => 4,
650 'trxn_id' => NULL,
651 'invoice_id' => NULL,
652 )
653 );
654 $this->contributionCreate(
655 array(
656 'contact_id' => $indv2,
657 'revenue_recognition_date' => date('Y-m-t', strtotime(date('ymd') . '+1 month')),
658 'financial_type_id' => 4,
659 'trxn_id' => NULL,
660 'invoice_id' => NULL,
661 )
662 );
663 $this->contributionCreate(
664 array(
665 'contact_id' => $indv2,
666 'receive_date' => '2016-03-01',
667 'revenue_recognition_date' => date('Y-m-t', strtotime(date('ymd') . '+4 month')),
668 'financial_type_id' => 2,
669 'trxn_id' => NULL,
670 'invoice_id' => NULL,
671 )
672 );
673 $rows = $this->callAPISuccess('report_template', 'getrows', array(
674 'report_id' => 'contribute/deferredrevenue',
675 ));
676 $this->assertEquals(2, $rows['count'], "Report failed to get row count");
677 $count = array(2, 1);
678 foreach ($rows['values'] as $row) {
679 $this->assertEquals(array_pop($count), count($row['rows']), "Report failed to get row count");
680 }
681 }
682
6a488035 683}