Merge pull request #4865 from eileenmcnaughton/my-first-factory
[civicrm-core.git] / tests / phpunit / WebTest / Contribute / OfflineContributionTest.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | CiviCRM version 4.6 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2014 |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License along 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 require_once 'CiviTest/CiviSeleniumTestCase.php';
29
30 /**
31 * Class WebTest_Contribute_OfflineContributionTest
32 */
33 class WebTest_Contribute_OfflineContributionTest extends CiviSeleniumTestCase {
34
35 protected function setUp() {
36 parent::setUp();
37 }
38
39 public function testStandaloneContributeAdd() {
40 $this->webtestLogin();
41
42 // Create a contact to be used as soft creditor
43 $softCreditFname = substr(sha1(rand()), 0, 7);
44 $softCreditLname = substr(sha1(rand()), 0, 7);
45 $this->webtestAddContact($softCreditFname, $softCreditLname, FALSE);
46
47 //financial account for check
48 $this->openCiviPage("admin/options/payment_instrument", "reset=1");
49 $financialAccount = $this->getText("xpath=//div[@id='payment_instrument']/table/tbody//tr/td[1]/div[text()='Check']/../../td[3]");
50
51 // Add new Financial Account
52 $orgName = 'Alberta ' . substr(sha1(rand()), 0, 7);
53 $financialAccountTitle = 'Financial Account ' . substr(sha1(rand()), 0, 4);
54 $financialAccountDescription = "{$financialAccountTitle} Description";
55 $accountingCode = 1033;
56 $financialAccountType = 'Asset';
57 $taxDeductible = FALSE;
58 $isActive = FALSE;
59 $isTax = TRUE;
60 $taxRate = 9;
61 $isDefault = FALSE;
62
63 //Add new organisation
64 if ($orgName) {
65 $this->webtestAddOrganization($orgName);
66 }
67
68 $this->_testAddFinancialAccount($financialAccountTitle,
69 $financialAccountDescription,
70 $accountingCode,
71 $orgName,
72 $financialAccountType,
73 $taxDeductible,
74 $isActive,
75 $isTax,
76 $taxRate,
77 $isDefault
78 );
79
80 $firstName = 'John' . substr(sha1(rand()), 0, 7);
81 $lastName = 'Dsouza' . substr(sha1(rand()), 0, 7);
82 $this->webtestAddContact($firstName, $lastName);
83
84 $this->waitForElementPresent("css=li#tab_contribute a");
85 $this->click("css=li#tab_contribute a");
86 $this->waitForElementPresent("link=Record Contribution (Check, Cash, EFT ...)");
87 $this->clickLink("link=Record Contribution (Check, Cash, EFT ...)", "_qf_Contribution_cancel-bottom", FALSE);
88
89 // select financial type
90 $this->select("financial_type_id", "value=1");
91
92 // fill in Received Date
93 $this->webtestFillDate('receive_date');
94
95 // source
96 $this->type("source", "Mailer 1");
97
98 // total amount
99 $this->type("total_amount", "100");
100
101 // select payment instrument type = Check and enter chk number
102 $this->select("payment_instrument_id", "value=4");
103 $this->waitForElementPresent("check_number");
104 $this->type("check_number", "check #1041");
105
106 $this->type("trxn_id", "P20901X1" . rand(100, 10000));
107
108 // create first soft credit
109 $this->click("softCredit");
110 $this->waitForElementPresent("soft_credit_amount_1");
111 $this->webtestFillAutocomplete("{$softCreditLname}, {$softCreditFname}", 's2id_soft_credit_contact_id_1');
112 $this->type("soft_credit_amount_1", "50");
113
114 // add second soft credit field
115 $this->click("addMoreSoftCredit");
116 $this->waitForElementPresent("soft_credit_amount_2");
117 // create new individual via soft credit
118 $softCreditSecondFname = substr(sha1(rand()), 0, 7);
119 $softCreditSecondLname = substr(sha1(rand()), 0, 7);
120 $this->webtestNewDialogContact($softCreditSecondFname, $softCreditSecondLname, NULL, 4, 's2id_soft_credit_contact_id_2', 'soft_credit_1');
121 // enter the second soft credit
122 $this->verifyText("soft_credit_amount_2", ""); // it should be blank cause first soft credit != total_amount
123 $this->type("soft_credit_amount_2", "100"); //the sum of the soft credit amounts can exceed total_amount
124 $this->select("soft_credit_type[2]", "In Honor of");
125
126 //Custom Data
127 // $this->click('CIVICRM_QFID_3_6');
128
129 //Additional Detail section
130 $this->click("AdditionalDetail");
131 $this->waitForElementPresent("thankyou_date");
132
133 $this->type("note", "This is a test note.");
134 $this->type("non_deductible_amount", "10.00");
135 $this->type("fee_amount", "0");
136 $this->type("net_amount", "0");
137 $this->type("invoice_id", time());
138 $this->webtestFillDate('thankyou_date');
139
140 //Premium section
141 $this->click("Premium");
142 $this->waitForElementPresent("fulfilled_date");
143 $this->select("product_name[0]", "label=Coffee Mug ( MUG-101 )");
144 $this->select("product_name[1]", "label=Black");
145 $this->webtestFillDate('fulfilled_date');
146
147 // Clicking save.
148 $this->click("_qf_Contribution_upload");
149
150 // Is status message correct?
151 //$this->assertTrue($this->isTextPresent("The contribution record has been saved."), "Status message didn't show up after saving!");
152
153 // verify if Contribution is created
154 $this->waitForElementPresent("xpath=//div[@class='view-content']//table[@class='selector row-highlight']//tbody/tr[1]/td[8]/span/a[text()='View']");
155
156 //click through to the Contribution view screen
157 $this->click("xpath=//div[@class='view-content']//table[@class='selector row-highlight']//tbody/tr[1]/td[8]/span/a[text()='View']");
158 $this->waitForElementPresent("_qf_ContributionView_cancel-bottom");
159
160 $expected = array(
161 'Financial Type' => 'Donation',
162 'Total Amount' => '100.00',
163 'Contribution Status' => 'Completed',
164 'Paid By' => 'Check',
165 'Check Number' => 'check #1041',
166 'Non-deductible Amount' => '10.00',
167 'Received Into' => $financialAccount,
168 );
169
170 $this->waitForElementPresent("xpath=//*[@id='ContributionView']/div[2]");
171 foreach ($expected as $value) {
172 $this->verifyText("xpath=//*[@id='ContributionView']/div[2]", preg_quote($value));
173 }
174
175 // verify if soft credit was created successfully
176 $expected = array(
177 'Soft Credit To 1' => "{$softCreditFname} {$softCreditLname}",
178 'Soft Credit To 2' => "{$softCreditSecondFname} {$softCreditSecondLname}",
179 'Amount (Soft Credit Type)' => '50.00 (Solicited)',
180 'Amount (Soft Credit Type)' => '100.00 (In Honor of)',
181 );
182
183 foreach ($expected as $value) {
184 $this->verifyText("css=table.crm-soft-credit-listing", preg_quote($value));
185 }
186
187 // go to first soft creditor contact view page
188 $this->clickLink("xpath=//*[@id='ContributionView']/div[2]/div[2]/div[2]/table/tbody/tr[1]/td[1]/a", "css=li#tab_contribute a");
189
190 // go to contribution tab
191 $this->click("css=li#tab_contribute a");
192 $this->waitForElementPresent("link=Record Contribution (Check, Cash, EFT ...)");
193
194 // verify soft credit details
195 $expected = array(
196 3 => 'Solicited',
197 4 => 'Donation',
198 2 => '50.00',
199 6 => 'Completed',
200 1 => "{$firstName} {$lastName}",
201 );
202 foreach ($expected as $value => $label) {
203 $this->verifyText("xpath=//div[@class='view-content']//table[@class='selector row-highlight']//tbody/tr[2]/td[$value]", preg_quote($label));
204 }
205 }
206
207 public function testDeductibleAmount() {
208 $this->webtestLogin();
209
210 //add authorize .net payment processor
211 $processorName = 'Webtest AuthNet' . substr(sha1(rand()), 0, 7);
212 $this->webtestAddPaymentProcessor($processorName, 'AuthNet');
213
214 $this->openCiviPage("admin/contribute/managePremiums", "action=add&reset=1");
215 $premiumName = 'test Premium' . substr(sha1(rand()), 0, 7);
216 $this->addPremium($premiumName, 'SKU', 3, 12, NULL, NULL);
217
218 $firstName = 'John' . substr(sha1(rand()), 0, 7);
219 $lastName = 'Dsouza' . substr(sha1(rand()), 0, 7);
220 $this->webtestAddContact($firstName, $lastName);
221
222 //scenario 1 : is_deductible = 0 and non deductible amount is entered
223 $scenario1 = array(
224 'financial_type' => 'Campaign Contribution',
225 'total_amount' => 111,
226 'non_deductible_amount' => 15,
227 'sort_name' => "$lastName, $firstName",
228 );
229 $this->_doOfflineContribution($scenario1, $firstName, $lastName, $processorName);
230
231 $checkScenario1 = array(
232 'From' => "{$firstName} {$lastName}",
233 'Financial Type' => 'Campaign Contribution',
234 'Total Amount' => 111,
235 'Non-deductible Amount' => 15,
236 'sort_name' => "$lastName, $firstName",
237 );
238 $this->_verifyAmounts($checkScenario1);
239
240 //scenario 2 : is_deductible = TRUE and premium is set and premium is greater than total amount
241 $scenario2 = array(
242 'financial_type' => 'Donation',
243 'total_amount' => 10,
244 'premium' => "{$premiumName} ( SKU )",
245 'sort_name' => "$lastName, $firstName",
246 );
247 $this->_doOfflineContribution($scenario2, $firstName, $lastName, $processorName);
248
249 $checkScenario2 = array(
250 'From' => "{$firstName} {$lastName}",
251 'Financial Type' => 'Donation',
252 'Total Amount' => 10,
253 'Non-deductible Amount' => 10,
254 'sort_name' => "$lastName, $firstName",
255 );
256 $this->_verifyAmounts($checkScenario2);
257
258 //scenario 3 : is_deductible = TRUE and premium is set and premium is less than total amount
259 $scenario3 = array(
260 'financial_type' => 'Donation',
261 'total_amount' => 123,
262 'premium' => "{$premiumName} ( SKU )",
263 'sort_name' => "$lastName, $firstName",
264 );
265 $this->_doOfflineContribution($scenario3, $firstName, $lastName, $processorName);
266
267 $checkScenario3 = array(
268 'From' => "{$firstName} {$lastName}",
269 'Financial Type' => 'Donation',
270 'Total Amount' => 123,
271 'Non-deductible Amount' => 12,
272 'sort_name' => "$lastName, $firstName",
273 );
274 $this->_verifyAmounts($checkScenario3);
275
276 //scenario 4 : is_deductible = TRUE and premium is not set
277 $scenario4 = array(
278 'financial_type' => 'Donation',
279 'total_amount' => 123,
280 'sort_name' => "$lastName, $firstName",
281 );
282 $this->_doOfflineContribution($scenario4, $firstName, $lastName, $processorName);
283
284 $checkScenario4 = array(
285 'From' => "{$firstName} {$lastName}",
286 'Financial Type' => 'Donation',
287 'Total Amount' => 123,
288 'Non-deductible Amount' => '0.00',
289 'sort_name' => "$lastName, $firstName",
290 );
291 $this->_verifyAmounts($checkScenario4);
292
293 //scenario 5 : is_deductible = FALSE, non_deductible_amount = the total amount
294 $scenario5 = array(
295 'financial_type' => 'Campaign Contribution',
296 'total_amount' => 555,
297 'sort_name' => "$lastName, $firstName",
298 );
299 $this->_doOfflineContribution($scenario5, $firstName, $lastName, $processorName);
300
301 $checkScenario5 = array(
302 'From' => "{$firstName} {$lastName}",
303 'Financial Type' => 'Campaign Contribution',
304 'Total Amount' => 555,
305 'Non-deductible Amount' => 555,
306 'sort_name' => "$lastName, $firstName",
307 );
308 $this->_verifyAmounts($checkScenario5);
309 }
310
311 //common function for doing offline contribution
312 /**
313 * @param array $params
314 * @param string $firstName
315 * @param string $lastName
316 * @param $processorName
317 */
318 public function _doOfflineContribution($params, $firstName, $lastName, $processorName) {
319
320 $this->waitForElementPresent("css=li#tab_contribute a");
321 $this->click("css=li#tab_contribute a");
322 $this->waitForElementPresent("link=Submit Credit Card Contribution");
323
324 // since we don't have live credentials we will switch to test mode
325 $url = $this->getAttribute("xpath=//*[@id='Search']/div[2]/div[2]/a[2]@href");
326 $url = str_replace('mode=live', 'mode=test', $url);
327 $this->open($url);
328 $this->waitForPageToLoad($this->getTimeoutMsec());
329
330 // start filling out contribution form
331 $this->waitForElementPresent('payment_processor_id');
332 $this->select('payment_processor_id', "label={$processorName}");
333
334 // select financial type
335 $this->select("financial_type_id", "label={$params['financial_type']}");
336
337 // total amount
338 $this->type("total_amount", "{$params['total_amount']}");
339
340 // enter credit card info on form
341 $this->webtestAddCreditCardDetails();
342
343 // billing address
344 $this->webtestAddBillingDetails($firstName, NULL, $lastName);
345
346 if ($nonDeductibleAmt = CRM_Utils_Array::value('non_deductible_amount', $params)) {
347 $this->click("AdditionalDetail");
348 $this->waitForElementPresent("thankyou_date");
349 $this->type("note", "This is a test note.");
350 $this->type("non_deductible_amount", "{$nonDeductibleAmt}");
351 }
352
353 if (!empty($params['premium'])) {
354 //Premium section
355 $this->click("Premium");
356 $this->waitForElementPresent("fulfilled_date");
357 $this->select("product_name[0]", "label={$params['premium']}");
358 }
359 // Clicking save.
360 $this->click("_qf_Contribution_upload");
361 $this->waitForPageToLoad($this->getTimeoutMsec());
362
363 // Is status message correct?
364 $this->assertTrue($this->isTextPresent("The contribution record has been processed."), "Status message didn't show up after saving!");
365 }
366
367 //common function for verifing total_amount, and non_deductible_amount
368 /**
369 * @param $verifyData
370 */
371 public function _verifyAmounts($verifyData) {
372 // since we are doing test contributions we need to search for test contribution and select first contribution
373 // record for the contact
374 $this->openCiviPage("contribute/search", "reset=1", "contribution_date_low");
375 $this->type("sort_name", $verifyData['sort_name']);
376
377 // select show test contributions
378 $this->click("contribution_test", "value=1");
379 $this->clickLink("_qf_Search_refresh", "xpath=//div[@id='contributionSearch']//table//tbody/tr[1]/td[11]/span/a[text()='View']");
380 $this->clickLink("xpath=//div[@id='contributionSearch']//table//tbody/tr[1]/td[11]/span/a[text()='View']", "_qf_ContributionView_cancel-bottom", FALSE);
381
382 foreach ($verifyData as $label => $value) {
383 if ($label == 'sort_name') {
384 continue;
385 }
386 $this->verifyText("xpath=//form[@id='ContributionView']//table/tbody/tr/td[text()='{$label}']/following-sibling::td",
387 preg_quote($value)
388 );
389 }
390
391 // now find contact and go back to contact summary
392 $this->openCiviPage("contact/search", "reset=1", "sort_name");
393 $this->type("sort_name", $verifyData['sort_name']);
394 $this->clickLink("_qf_Basic_refresh",
395 "xpath=//form[@id='Basic']/div[3]/div[1]/div[2]/table/tbody/tr[1]/td[11]/span/a[text()='View']");
396
397 $this->clickLink("xpath=//form[@id='Basic']/div[3]/div[1]/div[2]/table/tbody/tr[1]/td[11]/span/a[text()='View']",
398 'crm-contact-actions-link', FALSE);
399 }
400
401 public function testOnlineContributionWithZeroAmount() {
402 $this->webtestLogin();
403
404 // Create a contact to be used as soft creditor
405 $firstName = 'John' . substr(sha1(rand()), 0, 7);
406 $lastName = 'Peterson' . substr(sha1(rand()), 0, 7);
407 $this->webtestAddContact($firstName, $lastName);
408 $this->waitForElementPresent("css=li#tab_contribute a");
409 $this->click("css=li#tab_contribute a");
410 $this->waitForElementPresent("link=Record Contribution (Check, Cash, EFT ...)");
411 $this->clickLink("link=Record Contribution (Check, Cash, EFT ...)", "_qf_Contribution_cancel-bottom", FALSE);
412
413 // select financial type
414 $this->select("financial_type_id", "value=1");
415
416 // total amount
417 $this->type("total_amount", "0.00");
418
419 // select payment instrument
420 $this->select("payment_instrument_id", "value=1");
421
422 $this->type("trxn_id", "X20901X1" . rand(100, 10000));
423 $this->click('_qf_Contribution_upload-bottom');
424 $this->waitForText("crm-notification-container", "The contribution record has been saved.");
425
426 $this->waitForElementPresent("xpath=//div[@class='view-content']//table[@class='selector row-highlight']//tbody/tr[1]/td[8]/span/a[text()='View']");
427 $this->clickLink("xpath=//div[@class='view-content']//table[@class='selector row-highlight']//tbody/tr[1]/td[8]/span/a[text()='View']", "_qf_ContributionView_cancel-bottom", FALSE);
428 $expected = array(
429 'Financial Type' => 'Donation',
430 'Total Amount' => '0.00',
431 'Contribution Status' => 'Completed',
432 'Paid By' => 'Credit Card',
433 );
434 $this->webtestVerifyTabularData($expected);
435 }
436 }