]> git.agnieray.net Git - galette.git/blob - tests/Galette/Entity/tests/units/Transaction.php
8977ebb1213b7062ae3219d60bf4088422c619de
[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 $this->initContributionsTypes();
79
80 $this->contrib = new \Galette\Entity\Contribution($this->zdb, $this->login);
81 $this->transaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
82
83 $this->adh = new \Galette\Entity\Adherent($this->zdb);
84 $this->adh->setDependencies(
85 $this->preferences,
86 $this->members_fields,
87 $this->history
88 );
89 }
90
91 /**
92 * Create test transaction in database
93 *
94 * @return void
95 */
96 private function createTransaction()
97 {
98 $date = new \DateTime(); // 2020-11-07
99 $data = [
100 'id_adh' => $this->adh->id,
101 'trans_date' => $date->format('Y-m-d'),
102 'trans_amount' => 92,
103 'trans_desc' => 'FAKER' . $this->seed
104 ];
105
106 $this->transaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
107 $check = $this->transaction->check($data, [], []);
108 if (is_array($check)) {
109 var_dump($check);
110 }
111 $this->assertTrue($check);
112
113 $store = $this->transaction->store($this->history);
114 $this->assertTrue($store);
115
116 return $this->transaction;
117 }
118
119 /**
120 * Test empty transaction
121 *
122 * @return void
123 */
124 public function testEmpty()
125 {
126 $this->assertNull($this->transaction->id);
127 $this->assertEquals(date('Y-m-d'), $this->transaction->date);
128 $this->assertNull($this->transaction->amount);
129 $this->assertNull($this->transaction->description);
130
131 $this->assertSame((double)0, $this->transaction->getDispatchedAmount());
132 $this->assertSame((double)0, $this->transaction->getMissingAmount());
133 $this->assertSame('transaction-normal', $this->transaction->getRowClass());
134 $this->assertCount(6, $this->transaction->fields);
135 $this->assertArrayHasKey(\Galette\Entity\Transaction::PK, $this->transaction->fields);
136 $this->assertArrayHasKey(\Galette\Entity\Adherent::PK, $this->transaction->fields);
137 $this->assertArrayHasKey('trans_date', $this->transaction->fields);
138 $this->assertArrayHasKey('trans_amount', $this->transaction->fields);
139 $this->assertArrayHasKey('trans_desc', $this->transaction->fields);
140 $this->assertArrayHasKey('type_paiement_trans', $this->transaction->fields);
141
142 $this->assertEquals(false, $this->transaction->unknown_property);
143 }
144
145 /**
146 * Test getter and setter special cases
147 *
148 * @return void
149 */
150 public function testGetterSetter()
151 {
152 $transaction = $this->transaction;
153
154 //set a bad date
155 $data = ['trans_date' => 'mypassword'];
156 $expected = ['- Wrong date format (Y-m-d) for Date!'];
157 $check = $transaction->check($data, [], []);
158 $this->assertSame($expected, $check);
159
160 //set a correct date
161 $data = ['trans_date' => '1999-01-01'];
162 $check = $transaction->check($data, [], []);
163 $this->assertTrue($check);
164 $this->assertSame('1999-01-01', $transaction->date);
165
166 //set a bad amount
167 $data = ['trans_amount' => 'mypassword'];
168 $expected = ['- The amount must be an integer!'];
169 $check = $transaction->check($data, [], []);
170 $this->assertSame($expected, $check);
171
172 //set a correct amount
173 $data = ['trans_amount' => 1256];
174 $check = $transaction->check($data, ['trans_amount' => 1], []);
175 $this->assertTrue($check);
176 $this->assertSame(1256.00, $transaction->amount);
177
178 //set a bad description
179 $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.'];
180 $expected = ['- Transaction description must be 150 characters long maximum.'];
181 $check = $transaction->check($data, [], []);
182 $this->assertSame($expected, $check);
183 }
184
185 /**
186 * Test transaction creation
187 *
188 * @return void
189 */
190 public function testCreation()
191 {
192 $this->getMemberOne();
193 //create transaction for member
194 $this->createTransaction();
195 }
196
197 /**
198 * Test transaction update
199 *
200 * @return void
201 */
202 public function testUpdate()
203 {
204 $this->getMemberOne();
205 //create transaction for member
206 $this->createTransaction();
207
208 $this->logSuperAdmin();
209 $data = [
210 'trans_amount' => 42
211 ];
212 $check = $this->transaction->check($data, [], []);
213 if (is_array($check)) {
214 var_dump($check);
215 }
216 $this->assertTrue($check);
217
218 $store = $this->transaction->store($this->history);
219 $this->assertTrue($store);
220
221 $transaction = new \Galette\Entity\Transaction($this->zdb, $this->login, $this->transaction->id);
222 $this->assertSame(42.00, $transaction->amount);
223 }
224
225 /**
226 * Test fields labels
227 *
228 * @return void
229 */
230 public function testGetFieldLabel()
231 {
232 $this->assertSame(
233 'Amount',
234 $this->transaction->getFieldLabel('trans_amount')
235 );
236
237 $this->assertSame(
238 'Date',
239 $this->transaction->getFieldLabel('trans_date')
240 );
241
242 $this->assertSame(
243 'Description',
244 $this->transaction->getFieldLabel('trans_desc')
245 );
246
247 $this->assertSame(
248 'Originator',
249 $this->transaction->getFieldLabel(\Galette\Entity\Adherent::PK)
250 );
251 }
252
253 /**
254 * Test transaction loading
255 *
256 * @return void
257 */
258 public function testLoad()
259 {
260 $this->login = $this->getMockBuilder(\Galette\Core\Login::class)
261 ->setConstructorArgs(array($this->zdb, new \Galette\Core\I18n()))
262 ->onlyMethods(array('isLogged', 'isAdmin', 'isStaff'))
263 ->getMock();
264 $this->login->method('isLogged')->willReturn(true);
265 $this->login->method('isAdmin')->willReturn(true);
266 $this->login->method('isStaff')->willReturn(true);
267
268 $this->getMemberOne();
269
270 //create transaction for member
271 $this->createTransaction();
272
273 $id = $this->transaction->id;
274 $transaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
275
276 $this->assertTrue($transaction->load((int)$id));
277 $this->assertFalse($transaction->load(1355522012));
278 }
279
280 /**
281 * Test transaction removal
282 *
283 * @return void
284 */
285 public function testRemove()
286 {
287 $this->logSuperAdmin();
288
289 $this->getMemberOne();
290 $this->createTransaction();
291
292 $tid = $this->transaction->id;
293 $this->assertTrue($this->transaction->load($tid));
294 $this->assertTrue($this->transaction->remove($this->history));
295 $this->assertFalse($this->transaction->load($tid));
296 $this->assertFalse($this->transaction->remove($this->history));
297 }
298
299 /**
300 * Test can* methods
301 *
302 * @return void
303 */
304 public function testCan()
305 {
306 $this->getMemberOne();
307 //create transaction for member
308 $this->createTransaction();
309 $transaction = $this->transaction;
310
311 $this->assertFalse($transaction->canShow($this->login));
312
313 //Superadmin can fully change transactions
314 $this->logSuperAdmin();
315
316 $this->assertTrue($transaction->canShow($this->login));
317
318 //logout
319 $this->login->logOut();
320 $this->assertFalse($this->login->isLogged());
321
322 //Member can fully change its own transactions
323 $mdata = $this->dataAdherentOne();
324 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
325 $this->assertTrue($this->login->isLogged());
326 $this->assertFalse($this->login->isAdmin());
327 $this->assertFalse($this->login->isStaff());
328
329 $this->assertTrue($transaction->canShow($this->login));
330
331 //logout
332 $this->login->logOut();
333 $this->assertFalse($this->login->isLogged());
334
335 //Another member has no access
336 $this->getMemberTwo();
337 $mdata = $this->dataAdherentTwo();
338 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
339 $this->assertTrue($this->login->isLogged());
340 $this->assertFalse($this->login->isAdmin());
341 $this->assertFalse($this->login->isStaff());
342
343 $this->assertFalse($transaction->canShow($this->login));
344
345 //parents can chow change children transactions
346 $this->getMemberOne();
347 $member = $this->adh;
348 $mdata = $this->dataAdherentOne();
349 global $login;
350 $login = $this->login;
351 $this->logSuperAdmin();
352
353 $child_data = [
354 'nom_adh' => 'Doe',
355 'prenom_adh' => 'Johny',
356 'parent_id' => $member->id,
357 'attach' => true,
358 'login_adh' => 'child.johny.doe',
359 'fingerprint' => 'FAKER' . $this->seed
360 ];
361 $child = $this->createMember($child_data);
362 $cid = $child->id;
363
364 //transaction for child
365 $date = new \DateTime(); // 2020-11-07
366
367 $data = [
368 'id_adh' => $cid,
369 'trans_date' => $date->format('Y-m-d'),
370 'trans_amount' => 92,
371 'trans_desc' => 'FAKER' . $this->seed
372 ];
373
374 $ctransaction = new \Galette\Entity\Transaction($this->zdb, $this->login);
375 $check = $ctransaction->check($data, [], []);
376 if (is_array($check)) {
377 var_dump($check);
378 }
379 $this->assertTrue($check);
380
381 $store = $ctransaction->store($this->history);
382 $this->assertTrue($store);
383
384 $this->login->logOut();
385
386 //load child from db
387 $child = new \Galette\Entity\Adherent($this->zdb);
388 $child->enableDep('parent');
389 $this->assertTrue($child->load($cid));
390
391 $this->assertSame($child_data['nom_adh'], $child->name);
392 $this->assertInstanceOf('\Galette\Entity\Adherent', $child->parent);
393 $this->assertSame($member->id, $child->parent->id);
394 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
395
396 $mdata = $this->dataAdherentOne();
397 $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh']));
398 $this->assertTrue($this->login->isLogged());
399 $this->assertFalse($this->login->isAdmin());
400 $this->assertFalse($this->login->isStaff());
401
402 $this->assertTrue($ctransaction->canShow($this->login));
403
404 //logout
405 $this->login->logOut();
406 $this->assertFalse($this->login->isLogged());
407 }
408
409 /**
410 * Test a transaction
411 *
412 * @return void
413 */
414 public function testTransaction(): void
415 {
416 $this->logSuperAdmin();
417 $this->getMemberOne();
418 //create transaction for member
419 $this->createTransaction();
420
421 $contribs_ids = [];
422 $tid = $this->transaction->id;
423
424 //create a contribution attached to transaction
425 $bdate = new \DateTime(); // 2020-11-07
426 $bdate->sub(new \DateInterval('P5M')); // 2020-06-07
427 $bdate->add(new \DateInterval('P3D')); // 2020-06-10
428
429 $edate = clone $bdate;
430 $edate->add(new \DateInterval('P1Y'));
431
432 $data = [
433 'id_adh' => $this->adh->id,
434 'id_type_cotis' => 1,
435 'montant_cotis' => 25,
436 'type_paiement_cotis' => 3,
437 'info_cotis' => 'FAKER' . $this->seed,
438 'date_enreg' => $bdate->format('Y-m-d'),
439 'date_debut_cotis' => $bdate->format('Y-m-d'),
440 'date_fin_cotis' => $edate->format('Y-m-d'),
441 \Galette\Entity\Transaction::PK => $tid
442 ];
443 $contrib = $this->createContrib($data);
444 $contribs_ids[] = $contrib->id;
445
446 $this->assertTrue($contrib->isTransactionPart());
447 $this->assertTrue($contrib->isTransactionPartOf($this->transaction->id));
448
449 $this->assertSame(
450 (double)25,
451 $this->transaction->getDispatchedAmount()
452 );
453 $this->assertSame(
454 (double)67,
455 $this->transaction->getMissingAmount()
456 );
457 $this->assertSame('transaction-uncomplete', $this->transaction->getRowClass());
458
459 //complete the transaction
460 $data = [
461 'id_adh' => $this->adh->id,
462 'id_type_cotis' => 4, //donation
463 'montant_cotis' => 67,
464 'type_paiement_cotis' => 3,
465 'info_cotis' => 'FAKER' . $this->seed,
466 'date_enreg' => $bdate->format('Y-m-d'),
467 'date_debut_cotis' => $bdate->format('Y-m-d'),
468 'date_fin_cotis' => $edate->format('Y-m-d'),
469 \Galette\Entity\Transaction::PK => $tid
470 ];
471 $contrib = $this->createContrib($data);
472 $contribs_ids[] = $contrib->id;
473
474 $this->assertTrue($contrib->isTransactionPart());
475 $this->assertTrue($contrib->isTransactionPartOf($this->transaction->id));
476 $this->assertFalse($contrib->isFee());
477 $this->assertSame('Donation', $contrib->getTypeLabel());
478 $this->assertSame('donation', $contrib->getRawType());
479
480
481 $this->assertSame(
482 (double)92,
483 $this->transaction->getDispatchedAmount()
484 );
485 $this->assertSame(
486 (double)0,
487 $this->transaction->getMissingAmount()
488 );
489 $this->assertSame('transaction-normal', $this->transaction->getRowClass());
490
491 //cannot add more
492 $data = [
493 'id_adh' => $this->adh->id,
494 'id_type_cotis' => 4, //donation
495 'montant_cotis' => 36,
496 'type_paiement_cotis' => 3,
497 'info_cotis' => 'FAKER' . $this->seed,
498 'date_enreg' => $bdate->format('Y-m-d'),
499 'date_debut_cotis' => $bdate->format('Y-m-d'),
500 'date_fin_cotis' => $edate->format('Y-m-d'),
501 \Galette\Entity\Transaction::PK => $tid
502 ];
503 $contrib = new \Galette\Entity\Contribution($this->zdb, $this->login);
504 $check = $contrib->check($data, [], []);
505 $this->assertSame(['- Sum of all contributions exceed corresponding transaction amount.'], $check);
506
507 $contrib_id = $contribs_ids[0];
508 $contrib = new \Galette\Entity\Contribution($this->zdb, $this->login, $contrib_id);
509 $this->assertTrue($contrib->unsetTransactionPart($this->zdb, $this->login, $tid, $contrib_id));
510
511 $this->assertSame(
512 (double)67,
513 $this->transaction->getDispatchedAmount()
514 );
515 $this->assertSame(
516 (double)25,
517 $this->transaction->getMissingAmount()
518 );
519 $this->assertSame('transaction-uncomplete', $this->transaction->getRowClass());
520
521 $this->assertTrue($contrib->setTransactionPart($this->zdb, $tid, $contrib_id));
522
523 $this->assertSame(
524 (double)92,
525 $this->transaction->getDispatchedAmount()
526 );
527 $this->assertSame(
528 (double)0,
529 $this->transaction->getMissingAmount()
530 );
531 $this->assertSame('transaction-normal', $this->transaction->getRowClass());
532
533 //delete transaction, and ensures all contributions has been removed as well
534 $this->assertTrue($this->transaction->remove($this->history));
535 $this->assertFalse($this->transaction->load($tid));
536 foreach ($contribs_ids as $contrib_id) {
537 $this->assertFalse($this->contrib->load($contrib_id));
538 }
539 }
540 }