Commit | Line | Data |
---|---|---|
0ae57b4c KE |
1 | <?php |
2 | /** | |
3 | * Class CRM_Event_BAO_AdditionalPaymentTest | |
4 | * @group headless | |
5 | */ | |
6 | class CRM_Event_BAO_CRM19273 extends CiviUnitTestCase { | |
7 | ||
8 | protected $_priceSetID; | |
9 | protected $_cheapFee = 80; | |
10 | protected $_expensiveFee = 100; | |
11 | protected $_veryExpensive = 120; | |
12 | ||
13 | /** | |
14 | * @var int | |
15 | */ | |
16 | protected $contributionID; | |
17 | ||
18 | /** | |
19 | * @var int | |
20 | */ | |
21 | protected $participantID; | |
22 | ||
23 | /** | |
24 | * Price set field id. | |
25 | * | |
26 | * @var int | |
27 | */ | |
28 | protected $priceSetFieldID; | |
29 | ||
30 | /** | |
31 | * Set up for test. | |
32 | */ | |
33 | public function setUp() { | |
34 | parent::setUp(); | |
35 | $this->cleanup(); | |
36 | $this->_contactId = $this->individualCreate(); | |
37 | $event = $this->eventCreate(array('is_monetary' => 1)); | |
38 | $this->_eventId = $event['id']; | |
39 | $this->_priceSetID = $this->eventPriceSetCreate(); | |
40 | CRM_Price_BAO_PriceSet::addTo('civicrm_event', $this->_eventId, $this->_priceSetID); | |
41 | $priceSet = CRM_Price_BAO_PriceSet::getSetDetail($this->_priceSetID, TRUE, FALSE); | |
42 | $priceSet = CRM_Utils_Array::value($this->_priceSetID, $priceSet); | |
43 | $this->_feeBlock = CRM_Utils_Array::value('fields', $priceSet); | |
44 | $this->registerParticipantAndPay(); | |
45 | } | |
46 | ||
47 | /** | |
48 | * Clean up after test. | |
49 | */ | |
50 | public function tearDown() { | |
51 | $this->eventDelete($this->_eventId); | |
52 | $this->quickCleanUpFinancialEntities(); | |
53 | } | |
54 | ||
55 | ||
56 | /** | |
57 | * Remove default price field stuff. | |
58 | * | |
59 | * This is not actually good. However resolving this requires | |
60 | * a lot more fixes & we have a bit of work to do on event tests. | |
61 | * | |
62 | * @throws \Exception | |
63 | */ | |
64 | protected function cleanup() { | |
65 | $this->quickCleanup( | |
66 | array( | |
67 | 'civicrm_price_field_value', | |
68 | 'civicrm_price_field', | |
69 | 'civicrm_price_set', | |
70 | ) | |
71 | ); | |
72 | } | |
73 | ||
74 | /** | |
75 | * Create an event with a price set. | |
76 | * | |
77 | * @todo resolve this with parent function. | |
78 | * | |
79 | * @param int $amount | |
80 | * @param int $min_fee | |
81 | * @return int | |
82 | */ | |
83 | protected function eventPriceSetCreate($amount = 0, $min_fee = 0) { | |
84 | ||
85 | $paramsSet['title'] = 'Two Options'; | |
86 | $paramsSet['name'] = CRM_Utils_String::titleToVar('Two Options'); | |
87 | $paramsSet['is_active'] = FALSE; | |
88 | $paramsSet['extends'] = 1; | |
89 | ||
90 | $priceSet = CRM_Price_BAO_PriceSet::create($paramsSet); | |
91 | ||
92 | $paramsField = array( | |
93 | 'label' => 'Price Field', | |
94 | 'name' => CRM_Utils_String::titleToVar('Two Options'), | |
95 | 'html_type' => 'Radio', | |
96 | //'price' => $feeTotal, | |
97 | 'option_label' => array('1' => 'Expensive Room', '2' => "Cheap Room", '3' => 'Very Expensive'), | |
98 | 'option_value' => array('1' => 'E', '2' => 'C', '3' => 'V'), | |
99 | 'option_name' => array('1' => 'Expensive', '2' => "Cheap", "3" => "Very Expensive"), | |
100 | 'option_weight' => array('1' => 1, '2' => 2, '3' => 3), | |
101 | 'option_amount' => array('1' => $this->_expensiveFee, '2' => $this->_cheapFee, '3' => $this->_veryExpensive), | |
102 | 'is_display_amounts' => 1, | |
103 | 'weight' => 1, | |
104 | 'options_per_line' => 1, | |
105 | 'is_active' => array('1' => 1), | |
106 | 'price_set_id' => $priceSet->id, | |
107 | 'is_enter_qty' => 1, | |
108 | 'financial_type_id' => $this->getFinancialTypeId('Event Fee'), | |
109 | ); | |
110 | $field = CRM_Price_BAO_PriceField::create($paramsField); | |
111 | $this->priceSetFieldID = $field->id; | |
112 | return $priceSet->id; | |
113 | } | |
114 | ||
115 | /** | |
116 | * Get the total for the invoice. | |
117 | * | |
118 | * @param int $contributionId | |
119 | * @return mixed | |
120 | */ | |
121 | private function contributionInvoice($contributionId) { | |
122 | ||
123 | $query = " | |
124 | SELECT SUM(line_total) total | |
125 | FROM civicrm_line_item | |
126 | WHERE entity_table = 'civicrm_participant' | |
127 | AND entity_id = {$contributionId}"; | |
128 | $dao = CRM_Core_DAO::executeQuery($query); | |
129 | ||
130 | $this->assertTrue($dao->fetch(), "Succeeded retrieving invoicetotal"); | |
131 | return $dao->total; | |
132 | } | |
133 | ||
134 | /** | |
135 | * Get the total income from the participant record. | |
136 | * | |
137 | * @param int $participantId | |
138 | * | |
139 | * @return mixed | |
140 | */ | |
141 | private function totalIncome($participantId) { | |
142 | ||
143 | // @todo use INNER JOINS, this is not our style. | |
144 | $query = " | |
145 | SELECT SUM(et.amount) total | |
146 | FROM civicrm_entity_financial_trxn et | |
147 | , civicrm_financial_item fi | |
148 | , civicrm_line_item li | |
149 | WHERE et.entity_table='civicrm_financial_item' | |
150 | AND fi.id = et.entity_id | |
151 | AND fi.entity_table='civicrm_line_item' | |
152 | AND fi.entity_id = li.id | |
153 | AND li.entity_table = 'civicrm_participant' | |
154 | AND li.entity_id = ${participantId} | |
155 | "; | |
156 | $dao = CRM_Core_DAO::executeQuery($query); | |
157 | ||
158 | $this->assertTrue($dao->fetch(), "Succeeded retrieving total Income"); | |
159 | return $dao->total; | |
160 | } | |
161 | ||
162 | /** | |
163 | * Check the relevant entity balances. | |
164 | * | |
165 | * @param float $amount | |
166 | */ | |
167 | private function balanceCheck($amount) { | |
168 | $this->assertEquals($this->contributionInvoice($this->contributionID), $amount, "Invoice must a total of $amount"); | |
169 | $this->assertEquals($this->totalIncome($this->participantID), $amount, "The recorded income must be $amount "); | |
170 | $this->assertEquals($this->totalIncome($this->contributionID), $amount, "The accumulated assets must be $amount "); | |
171 | } | |
172 | ||
173 | /** | |
174 | * Prepare records for editing. | |
175 | */ | |
176 | public function registerParticipantAndPay() { | |
177 | $params = array( | |
178 | 'send_receipt' => 1, | |
179 | 'is_test' => 0, | |
180 | 'is_pay_later' => 0, | |
181 | 'event_id' => $this->_eventId, | |
182 | 'register_date' => date('Y-m-d') . " 00:00:00", | |
183 | 'role_id' => 1, | |
184 | 'status_id' => 1, | |
185 | 'source' => 'Event_' . $this->_eventId, | |
186 | 'contact_id' => $this->_contactId, | |
187 | //'fee_level' => CRM_Core_DAO::VALUE_SEPARATOR.'Expensive Room'.CRM_Core_DAO::VALUE_SEPARATOR, | |
188 | ); | |
189 | $participant = $this->callAPISuccess('Participant', 'create', $params); | |
190 | $this->_participantId = $participant['id']; | |
191 | ||
192 | $actualPaidAmt = $this->_expensiveFee; | |
193 | ||
194 | $contributionParams = array( | |
195 | 'total_amount' => $actualPaidAmt, | |
196 | 'source' => 'Testset with information', | |
197 | 'currency' => 'USD', | |
198 | 'non_deductible_amount' => 'null', | |
199 | 'receipt_date' => date('Y-m-d') . " 00:00:00", | |
200 | 'contact_id' => $this->_contactId, | |
201 | 'financial_type_id' => 4, | |
202 | 'payment_instrument_id' => 4, | |
203 | 'contribution_status_id' => 1, | |
204 | 'receive_date' => date('Y-m-d') . " 00:00:00", | |
205 | 'skipLineItem' => 1, | |
206 | 'partial_payment_total' => $this->_expensiveFee, | |
207 | 'partial_amount_pay' => $actualPaidAmt, | |
208 | ); | |
209 | ||
210 | $contribution = CRM_Contribute_BAO_Contribution::create($contributionParams); | |
211 | $this->_contributionId = $contribution->id; | |
212 | ||
213 | $this->callAPISuccess('participant_payment', 'create', array( | |
214 | 'participant_id' => $this->_participantId, | |
215 | 'contribution_id' => $this->_contributionId, | |
216 | )); | |
217 | ||
218 | $PSparams['price_1'] = 1; // 1 is the option of the expensive room | |
219 | $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant'); | |
220 | CRM_Price_BAO_PriceSet::processAmount($this->_feeBlock, $PSparams, $lineItem); | |
221 | $lineItemVal[$this->_priceSetID] = $lineItem; | |
222 | CRM_Price_BAO_LineItem::processPriceSet($participant['id'], $lineItemVal, $contribution, 'civicrm_participant'); | |
223 | ||
224 | $this->contributionID = $this->callAPISuccessGetValue('Contribution', array('return' => 'id')); | |
225 | $this->participantID = $this->callAPISuccessGetValue('Participant', array('return' => 'id')); | |
226 | $this->balanceCheck($this->_expensiveFee); | |
227 | } | |
228 | ||
229 | public function testCRM19273() { | |
230 | ||
231 | $PSparams['price_1'] = 2; | |
232 | $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant'); | |
233 | CRM_Event_BAO_Participant::changeFeeSelections($PSparams, $this->participantID, $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee, $this->_priceSetID); | |
234 | $this->balanceCheck($this->_cheapFee); | |
235 | ||
236 | $PSparams['price_1'] = 1; | |
237 | $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant'); | |
238 | CRM_Event_BAO_Participant::changeFeeSelections($PSparams, $this->participantID, $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee, $this->_priceSetID); | |
239 | $this->balanceCheck($this->_expensiveFee); | |
240 | ||
241 | $PSparams['price_1'] = 3; | |
242 | $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant'); | |
243 | ||
244 | CRM_Event_BAO_Participant::changeFeeSelections($PSparams, $this->participantID, $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee, $this->_priceSetID); | |
245 | $this->balanceCheck($this->_veryExpensive); | |
aa84923f | 246 | |
247 | } | |
248 | ||
249 | /** | |
250 | * Test that proper financial items are recorded for cancelled line items | |
251 | */ | |
252 | public function testCRM20611() { | |
253 | $PSparams['price_1'] = 1; | |
254 | $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant'); | |
255 | CRM_Event_BAO_Participant::changeFeeSelections($PSparams, $this->participantID, $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee, $this->_priceSetID); | |
256 | $this->balanceCheck($this->_expensiveFee); | |
257 | ||
258 | $PSparams['price_1'] = 2; | |
259 | $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant'); | |
260 | CRM_Event_BAO_Participant::changeFeeSelections($PSparams, $this->participantID, $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee, $this->_priceSetID); | |
261 | $this->balanceCheck($this->_cheapFee); | |
262 | ||
263 | //Complete the refund payment. | |
264 | $submittedValues = array( | |
265 | 'total_amount' => 120, | |
266 | 'payment_instrument_id' => 3, | |
267 | ); | |
268 | CRM_Contribute_BAO_Contribution::recordAdditionalPayment($this->_contributionId, $submittedValues, 'refund', $this->participantID); | |
269 | ||
270 | // retrieve the cancelled line-item information | |
271 | $cancelledLineItem = $this->callAPISuccessGetSingle('LineItem', array( | |
272 | 'entity_table' => 'civicrm_participant', | |
273 | 'entity_id' => $this->participantID, | |
274 | 'qty' => 0, | |
275 | )); | |
276 | // retrieve the related financial lin-items | |
277 | $financialItems = $this->callAPISuccess('FinancialItem', 'Get', array( | |
278 | 'entity_id' => $cancelledLineItem['id'], | |
279 | 'entity_table' => 'civicrm_line_item', | |
280 | )); | |
281 | $this->assertEquals($financialItems['count'], 2, 'Financial Items for Cancelled fee is not proper'); | |
282 | ||
283 | $contributionCompletedStatusID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); | |
284 | $expectedAmount = 100.00; | |
285 | foreach ($financialItems['values'] as $id => $financialItem) { | |
286 | $this->assertEquals($expectedAmount, $financialItem['amount']); | |
287 | $this->assertNotEmpty($financialItem['financial_account_id']); | |
288 | $this->assertEquals($contributionCompletedStatusID, $financialItem['status_id']); | |
289 | $expectedAmount = -$expectedAmount; | |
290 | } | |
0ae57b4c KE |
291 | } |
292 | ||
293 | } |