]> git.agnieray.net Git - galette.git/blob - tests/Galette/Entity/tests/units/Transaction.php
Instanciate titles, models, status, ...
[galette.git] / tests / Galette / Entity / tests / units / Transaction.php
1 <?php
2
3 /**
4 * Copyright © 2003-2024 The Galette Team
5 *
6 * This file is part of Galette (https://galette.eu).
7 *
8 * Galette is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Galette is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 namespace Galette\Entity\test\units;
23
24 use Galette\GaletteTestCase;
25
26 /**
27 * Transaction tests class
28 *
29 * @author Johan Cwiklinski <johan@x-tnd.be>
30 */
31 class Transaction extends GaletteTestCase
32 {
33 protected int $seed = 95842354;
34 /** @var \Galette\Entity\Transaction */
35 private \Galette\Entity\Transaction $transaction;
36
37 /**
38 * Cleanup after each test method
39 *
40 * @return void
41 */
42 public function tearDown(): void
43 {
44 parent::tearDown();
45
46 $this->zdb = new \Galette\Core\Db();
47
48 //first, remove contributions
49 $delete = $this->zdb->delete(\Galette\Entity\Contribution::TABLE);
50 $delete->where(['info_cotis' => 'FAKER' . $this->seed]);
51 $this->zdb->execute($delete);
52
53 //then, remove transactions
54 $delete = $this->zdb->delete(\Galette\Entity\Transaction::TABLE);
55 $delete->where(['trans_desc' => 'FAKER' . $this->seed]);
56 $this->zdb->execute($delete);
57
58 //remove members with parents
59 $delete = $this->zdb->delete(\Galette\Entity\Adherent::TABLE);
60 $delete->where(['fingerprint' => 'FAKER' . $this->seed]);
61 $delete->where('parent_id IS NOT NULL');
62 $this->zdb->execute($delete);
63
64 //remove all others members
65 $delete = $this->zdb->delete(\Galette\Entity\Adherent::TABLE);
66 $delete->where(['fingerprint' => 'FAKER' . $this->seed]);
67 $this->zdb->execute($delete);
68 }
69
70 /**
71 * Set up tests
72 *
73 * @return void
74 */
75 public function setUp(): void
76 {
77 parent::setUp();
78
79 $this->contrib = new \Galette\Entity\Contribution($this->zdb, $this->login);
80 $this->transaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
81
82 $this->adh = new \Galette\Entity\Adherent($this->zdb);
83 $this->adh->setDependencies(
84 $this->preferences,
85 $this->members_fields,
86 $this->history
87 );
88 }
89
90 /**
91 * Create test transaction in database
92 *
93 * @return void
94 */
95 private function createTransaction()
96 {
97 $date = new \DateTime(); // 2020-11-07
98 $data = [
99 'id_adh' => $this->adh->id,
100 'trans_date' => $date->format('Y-m-d'),
101 'trans_amount' => 92,
102 'trans_desc' => 'FAKER' . $this->seed
103 ];
104
105 $this->transaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
106 $check = $this->transaction->check($data, [], []);
107 if (is_array($check)) {
108 var_dump($check);
109 }
110 $this->assertTrue($check);
111
112 $store = $this->transaction->store($this->history);
113 $this->assertTrue($store);
114
115 return $this->transaction;
116 }
117
118 /**
119 * Test empty transaction
120 *
121 * @return void
122 */
123 public function testEmpty()
124 {
125 $this->assertNull($this->transaction->id);
126 $this->assertEquals(date('Y-m-d'), $this->transaction->date);
127 $this->assertNull($this->transaction->amount);
128 $this->assertNull($this->transaction->description);
129
130 $this->assertSame((double)0, $this->transaction->getDispatchedAmount());
131 $this->assertSame((double)0, $this->transaction->getMissingAmount());
132 $this->assertSame('transaction-normal', $this->transaction->getRowClass());
133 $this->assertCount(6, $this->transaction->fields);
134 $this->assertArrayHasKey(\Galette\Entity\Transaction::PK, $this->transaction->fields);
135 $this->assertArrayHasKey(\Galette\Entity\Adherent::PK, $this->transaction->fields);
136 $this->assertArrayHasKey('trans_date', $this->transaction->fields);
137 $this->assertArrayHasKey('trans_amount', $this->transaction->fields);
138 $this->assertArrayHasKey('trans_desc', $this->transaction->fields);
139 $this->assertArrayHasKey('type_paiement_trans', $this->transaction->fields);
140
141 $this->assertEquals(false, $this->transaction->unknown_property);
142 }
143
144 /**
145 * Test getter and setter special cases
146 *
147 * @return void
148 */
149 public function testGetterSetter()
150 {
151 $transaction = $this->transaction;
152
153 //set a bad date
154 $data = ['trans_date' => 'mypassword'];
155 $expected = ['- Wrong date format (Y-m-d) for Date!'];
156 $check = $transaction->check($data, [], []);
157 $this->assertSame($expected, $check);
158
159 //set a correct date
160 $data = ['trans_date' => '1999-01-01'];
161 $check = $transaction->check($data, [], []);
162 $this->assertTrue($check);
163 $this->assertSame('1999-01-01', $transaction->date);
164
165 //set a bad amount
166 $data = ['trans_amount' => 'mypassword'];
167 $expected = ['- The amount must be an integer!'];
168 $check = $transaction->check($data, [], []);
169 $this->assertSame($expected, $check);
170
171 //set a correct amount
172 $data = ['trans_amount' => 1256];
173 $check = $transaction->check($data, ['trans_amount' => 1], []);
174 $this->assertTrue($check);
175 $this->assertSame(1256.00, $transaction->amount);
176
177 //set a bad description
178 $data = ['trans_desc' => 'this is a very long description that should give an error; because the length of transaction description is limited to 150 characters long, even if this is quite hard to find something to write.'];
179 $expected = ['- Transaction description must be 150 characters long maximum.'];
180 $check = $transaction->check($data, [], []);
181 $this->assertSame($expected, $check);
182 }
183
184 /**
185 * Test transaction creation
186 *
187 * @return void
188 */
189 public function testCreation()
190 {
191 $this->getMemberOne();
192 //create transaction for member
193 $this->createTransaction();
194 }
195
196 /**
197 * Test transaction update
198 *
199 * @return void
200 */
201 public function testUpdate()
202 {
203 $this->getMemberOne();
204 //create transaction for member
205 $this->createTransaction();
206
207 $this->logSuperAdmin();
208 $data = [
209 'trans_amount' => 42
210 ];
211 $check = $this->transaction->check($data, [], []);
212 if (is_array($check)) {
213 var_dump($check);
214 }
215 $this->assertTrue($check);
216
217 $store = $this->transaction->store($this->history);
218 $this->assertTrue($store);
219
220 $transaction = new \Galette\Entity\Transaction($this->zdb, $this->login, $this->transaction->id);
221 $this->assertSame(42.00, $transaction->amount);
222 }
223
224 /**
225 * Test fields labels
226 *
227 * @return void
228 */
229 public function testGetFieldLabel()
230 {
231 $this->assertSame(
232 'Amount',
233 $this->transaction->getFieldLabel('trans_amount')
234 );
235
236 $this->assertSame(
237 'Date',
238 $this->transaction->getFieldLabel('trans_date')
239 );
240
241 $this->assertSame(
242 'Description',
243 $this->transaction->getFieldLabel('trans_desc')
244 );
245
246 $this->assertSame(
247 'Originator',
248 $this->transaction->getFieldLabel(\Galette\Entity\Adherent::PK)
249 );
250 }
251
252 /**
253 * Test transaction loading
254 *
255 * @return void
256 */
257 public function testLoad()
258 {
259 $this->login = $this->getMockBuilder(\Galette\Core\Login::class)
260 ->setConstructorArgs(array($this->zdb, new \Galette\Core\I18n()))
261 ->onlyMethods(array('isLogged', 'isAdmin', 'isStaff'))
262 ->getMock();
263 $this->login->method('isLogged')->willReturn(true);
264 $this->login->method('isAdmin')->willReturn(true);
265 $this->login->method('isStaff')->willReturn(true);
266
267 $this->getMemberOne();
268
269 //create transaction for member
270 $this->createTransaction();
271
272 $id = $this->transaction->id;
273 $transaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
274
275 $this->assertTrue($transaction->load((int)$id));
276 $this->assertFalse($transaction->load(1355522012));
277 }
278
279 /**
280 * Test transaction removal
281 *
282 * @return void
283 */
284 public function testRemove()
285 {
286 $this->logSuperAdmin();
287
288 $this->getMemberOne();
289 $this->createTransaction();
290
291 $tid = $this->transaction->id;
292 $this->assertTrue($this->transaction->load($tid));
293 $this->assertTrue($this->transaction->remove($this->history));
294 $this->assertFalse($this->transaction->load($tid));
295 $this->assertFalse($this->transaction->remove($this->history));
296 }
297
298 /**
299 * Test can* methods
300 *
301 * @return void
302 */
303 public function testCan()
304 {
305 $this->getMemberOne();
306 //create transaction for member
307 $this->createTransaction();
308 $transaction = $this->transaction;
309
310 $this->assertFalse($transaction->canShow($this->login));
311
312 //Superadmin can fully change transactions
313 $this->logSuperAdmin();
314
315 $this->assertTrue($transaction->canShow($this->login));
316
317 //logout
318 $this->login->logOut();
319 $this->assertFalse($this->login->isLogged());
320
321 //Member can fully change its own transactions
322 $mdata = $this->dataAdherentOne();
323 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
324 $this->assertTrue($this->login->isLogged());
325 $this->assertFalse($this->login->isAdmin());
326 $this->assertFalse($this->login->isStaff());
327
328 $this->assertTrue($transaction->canShow($this->login));
329
330 //logout
331 $this->login->logOut();
332 $this->assertFalse($this->login->isLogged());
333
334 //Another member has no access
335 $this->getMemberTwo();
336 $mdata = $this->dataAdherentTwo();
337 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
338 $this->assertTrue($this->login->isLogged());
339 $this->assertFalse($this->login->isAdmin());
340 $this->assertFalse($this->login->isStaff());
341
342 $this->assertFalse($transaction->canShow($this->login));
343
344 //parents can chow change children transactions
345 $this->getMemberOne();
346 $member = $this->adh;
347 $mdata = $this->dataAdherentOne();
348 global $login;
349 $login = $this->login;
350 $this->logSuperAdmin();
351
352 $child_data = [
353 'nom_adh' => 'Doe',
354 'prenom_adh' => 'Johny',
355 'parent_id' => $member->id,
356 'attach' => true,
357 'login_adh' => 'child.johny.doe',
358 'fingerprint' => 'FAKER' . $this->seed
359 ];
360 $child = $this->createMember($child_data);
361 $cid = $child->id;
362
363 //transaction for child
364 $date = new \DateTime(); // 2020-11-07
365
366 $data = [
367 'id_adh' => $cid,
368 'trans_date' => $date->format('Y-m-d'),
369 'trans_amount' => 92,
370 'trans_desc' => 'FAKER' . $this->seed
371 ];
372
373 $ctransaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
374 $check = $ctransaction->check($data, [], []);
375 if (is_array($check)) {
376 var_dump($check);
377 }
378 $this->assertTrue($check);
379
380 $store = $ctransaction->store($this->history);
381 $this->assertTrue($store);
382
383 $this->login->logOut();
384
385 //load child from db
386 $child = new \Galette\Entity\Adherent($this->zdb);
387 $child->enableDep('parent');
388 $this->assertTrue($child->load($cid));
389
390 $this->assertSame($child_data['nom_adh'], $child->name);
391 $this->assertInstanceOf('\Galette\Entity\Adherent', $child->parent);
392 $this->assertSame($member->id, $child->parent->id);
393 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
394
395 $mdata = $this->dataAdherentOne();
396 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
397 $this->assertTrue($this->login->isLogged());
398 $this->assertFalse($this->login->isAdmin());
399 $this->assertFalse($this->login->isStaff());
400
401 $this->assertTrue($ctransaction->canShow($this->login));
402
403 //logout
404 $this->login->logOut();
405 $this->assertFalse($this->login->isLogged());
406 }
407
408 /**
409 * Test a transaction
410 *
411 * @return void
412 */
413 public function testTransaction(): void
414 {
415 $this->logSuperAdmin();
416 $this->getMemberOne();
417 //create transaction for member
418 $this->createTransaction();
419
420 $contribs_ids = [];
421 $tid = $this->transaction->id;
422
423 //create a contribution attached to transaction
424 $bdate = new \DateTime(); // 2020-11-07
425 $bdate->sub(new \DateInterval('P5M')); // 2020-06-07
426 $bdate->add(new \DateInterval('P3D')); // 2020-06-10
427
428 $edate = clone $bdate;
429 $edate->add(new \DateInterval('P1Y'));
430
431 $data = [
432 'id_adh' => $this->adh->id,
433 'id_type_cotis' => 1,
434 'montant_cotis' => 25,
435 'type_paiement_cotis' => 3,
436 'info_cotis' => 'FAKER' . $this->seed,
437 'date_enreg' => $bdate->format('Y-m-d'),
438 'date_debut_cotis' => $bdate->format('Y-m-d'),
439 'date_fin_cotis' => $edate->format('Y-m-d'),
440 \Galette\Entity\Transaction::PK => $tid
441 ];
442 $contrib = $this->createContrib($data);
443 $contribs_ids[] = $contrib->id;
444
445 $this->assertTrue($contrib->isTransactionPart());
446 $this->assertTrue($contrib->isTransactionPartOf($this->transaction->id));
447
448 $this->assertSame(
449 (double)25,
450 $this->transaction->getDispatchedAmount()
451 );
452 $this->assertSame(
453 (double)67,
454 $this->transaction->getMissingAmount()
455 );
456 $this->assertSame('transaction-uncomplete', $this->transaction->getRowClass());
457
458 //complete the transaction
459 $data = [
460 'id_adh' => $this->adh->id,
461 'id_type_cotis' => 4, //donation
462 'montant_cotis' => 67,
463 'type_paiement_cotis' => 3,
464 'info_cotis' => 'FAKER' . $this->seed,
465 'date_enreg' => $bdate->format('Y-m-d'),
466 'date_debut_cotis' => $bdate->format('Y-m-d'),
467 'date_fin_cotis' => $edate->format('Y-m-d'),
468 \Galette\Entity\Transaction::PK => $tid
469 ];
470 $contrib = $this->createContrib($data);
471 $contribs_ids[] = $contrib->id;
472
473 $this->assertTrue($contrib->isTransactionPart());
474 $this->assertTrue($contrib->isTransactionPartOf($this->transaction->id));
475 $this->assertFalse($contrib->isFee());
476 $this->assertSame('Donation', $contrib->getTypeLabel());
477 $this->assertSame('donation', $contrib->getRawType());
478
479
480 $this->assertSame(
481 (double)92,
482 $this->transaction->getDispatchedAmount()
483 );
484 $this->assertSame(
485 (double)0,
486 $this->transaction->getMissingAmount()
487 );
488 $this->assertSame('transaction-normal', $this->transaction->getRowClass());
489
490 //cannot add more
491 $data = [
492 'id_adh' => $this->adh->id,
493 'id_type_cotis' => 4, //donation
494 'montant_cotis' => 36,
495 'type_paiement_cotis' => 3,
496 'info_cotis' => 'FAKER' . $this->seed,
497 'date_enreg' => $bdate->format('Y-m-d'),
498 'date_debut_cotis' => $bdate->format('Y-m-d'),
499 'date_fin_cotis' => $edate->format('Y-m-d'),
500 \Galette\Entity\Transaction::PK => $tid
501 ];
502 $contrib = new \Galette\Entity\Contribution($this->zdb, $this->login);
503 $check = $contrib->check($data, [], []);
504 $this->assertSame(['- Sum of all contributions exceed corresponding transaction amount.'], $check);
505
506 $contrib_id = $contribs_ids[0];
507 $contrib = new \Galette\Entity\Contribution($this->zdb, $this->login, $contrib_id);
508 $this->assertTrue($contrib->unsetTransactionPart($this->zdb, $this->login, $tid, $contrib_id));
509
510 $this->assertSame(
511 (double)67,
512 $this->transaction->getDispatchedAmount()
513 );
514 $this->assertSame(
515 (double)25,
516 $this->transaction->getMissingAmount()
517 );
518 $this->assertSame('transaction-uncomplete', $this->transaction->getRowClass());
519
520 $this->assertTrue($contrib->setTransactionPart($this->zdb, $tid, $contrib_id));
521
522 $this->assertSame(
523 (double)92,
524 $this->transaction->getDispatchedAmount()
525 );
526 $this->assertSame(
527 (double)0,
528 $this->transaction->getMissingAmount()
529 );
530 $this->assertSame('transaction-normal', $this->transaction->getRowClass());
531
532 //delete transaction, and ensures all contributions has been removed as well
533 $this->assertTrue($this->transaction->remove($this->history));
534 $this->assertFalse($this->transaction->load($tid));
535 foreach ($contribs_ids as $contrib_id) {
536 $this->assertFalse($this->contrib->load($contrib_id));
537 }
538 }
539 }