4 * Copyright © 2003-2024 The Galette Team
6 * This file is part of Galette (https://galette.eu).
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.
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.
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/>.
22 namespace Galette\Entity\test\units
;
24 use Galette\GaletteTestCase
;
27 * Transaction tests class
29 * @author Johan Cwiklinski <johan@x-tnd.be>
31 class Transaction
extends GaletteTestCase
33 protected int $seed = 95842354;
34 /** @var \Galette\Entity\Transaction */
35 private \Galette\Entity\Transaction
$transaction;
38 * Cleanup after each test method
42 public function tearDown(): void
46 $this->zdb
= new \Galette\Core\
Db();
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);
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);
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);
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);
75 public function setUp(): void
79 $this->contrib
= new \Galette\Entity\
Contribution($this->zdb
, $this->login
);
80 $this->transaction
= new \Galette\Entity\
Transaction($this->zdb
, $this->login
);
82 $this->adh
= new \Galette\Entity\
Adherent($this->zdb
);
83 $this->adh
->setDependencies(
85 $this->members_fields
,
91 * Create test transaction in database
95 private function createTransaction()
97 $date = new \
DateTime(); // 2020-11-07
99 'id_adh' => $this->adh
->id
,
100 'trans_date' => $date->format('Y-m-d'),
101 'trans_amount' => 92,
102 'trans_desc' => 'FAKER' . $this->seed
105 $this->transaction
= new \Galette\Entity\
Transaction($this->zdb
, $this->login
);
106 $check = $this->transaction
->check($data, [], []);
107 if (is_array($check)) {
110 $this->assertTrue($check);
112 $store = $this->transaction
->store($this->history
);
113 $this->assertTrue($store);
115 return $this->transaction
;
119 * Test empty transaction
123 public function testEmpty()
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
);
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
);
141 $this->assertEquals(false, $this->transaction
->unknown_property
);
145 * Test getter and setter special cases
149 public function testGetterSetter()
151 $transaction = $this->transaction
;
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);
160 $data = ['trans_date' => '1999-01-01'];
161 $check = $transaction->check($data, [], []);
162 $this->assertTrue($check);
163 $this->assertSame('1999-01-01', $transaction->date
);
166 $data = ['trans_amount' => 'mypassword'];
167 $expected = ['- The amount must be an integer!'];
168 $check = $transaction->check($data, [], []);
169 $this->assertSame($expected, $check);
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
);
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);
185 * Test transaction creation
189 public function testCreation()
191 $this->getMemberOne();
192 //create transaction for member
193 $this->createTransaction();
197 * Test transaction update
201 public function testUpdate()
203 $this->getMemberOne();
204 //create transaction for member
205 $this->createTransaction();
207 $this->logSuperAdmin();
211 $check = $this->transaction
->check($data, [], []);
212 if (is_array($check)) {
215 $this->assertTrue($check);
217 $store = $this->transaction
->store($this->history
);
218 $this->assertTrue($store);
220 $transaction = new \Galette\Entity\
Transaction($this->zdb
, $this->login
, $this->transaction
->id
);
221 $this->assertSame(42.00, $transaction->amount
);
229 public function testGetFieldLabel()
233 $this->transaction
->getFieldLabel('trans_amount')
238 $this->transaction
->getFieldLabel('trans_date')
243 $this->transaction
->getFieldLabel('trans_desc')
248 $this->transaction
->getFieldLabel(\Galette\Entity\Adherent
::PK
)
253 * Test transaction loading
257 public function testLoad()
259 $this->login
= $this->getMockBuilder(\Galette\Core\Login
::class)
260 ->setConstructorArgs(array($this->zdb
, new \Galette\Core\
I18n()))
261 ->onlyMethods(array('isLogged', 'isAdmin', 'isStaff'))
263 $this->login
->method('isLogged')->willReturn(true);
264 $this->login
->method('isAdmin')->willReturn(true);
265 $this->login
->method('isStaff')->willReturn(true);
267 $this->getMemberOne();
269 //create transaction for member
270 $this->createTransaction();
272 $id = $this->transaction
->id
;
273 $transaction = new \Galette\Entity\
Transaction($this->zdb
, $this->login
);
275 $this->assertTrue($transaction->load((int)$id));
276 $this->assertFalse($transaction->load(1355522012));
280 * Test transaction removal
284 public function testRemove()
286 $this->logSuperAdmin();
288 $this->getMemberOne();
289 $this->createTransaction();
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
));
303 public function testCan()
305 $this->getMemberOne();
306 //create transaction for member
307 $this->createTransaction();
308 $transaction = $this->transaction
;
310 $this->assertFalse($transaction->canShow($this->login
));
312 //Superadmin can fully change transactions
313 $this->logSuperAdmin();
315 $this->assertTrue($transaction->canShow($this->login
));
318 $this->login
->logOut();
319 $this->assertFalse($this->login
->isLogged());
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());
328 $this->assertTrue($transaction->canShow($this->login
));
331 $this->login
->logOut();
332 $this->assertFalse($this->login
->isLogged());
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());
342 $this->assertFalse($transaction->canShow($this->login
));
344 //parents can chow change children transactions
345 $this->getMemberOne();
346 $member = $this->adh
;
347 $mdata = $this->dataAdherentOne();
349 $login = $this->login
;
350 $this->logSuperAdmin();
354 'prenom_adh' => 'Johny',
355 'parent_id' => $member->id
,
357 'login_adh' => 'child.johny.doe',
358 'fingerprint' => 'FAKER' . $this->seed
360 $child = $this->createMember($child_data);
363 //transaction for child
364 $date = new \
DateTime(); // 2020-11-07
368 'trans_date' => $date->format('Y-m-d'),
369 'trans_amount' => 92,
370 'trans_desc' => 'FAKER' . $this->seed
373 $ctransaction = new \Galette\Entity\
Transaction($this->zdb
, $this->login
);
374 $check = $ctransaction->check($data, [], []);
375 if (is_array($check)) {
378 $this->assertTrue($check);
380 $store = $ctransaction->store($this->history
);
381 $this->assertTrue($store);
383 $this->login
->logOut();
386 $child = new \Galette\Entity\
Adherent($this->zdb
);
387 $child->enableDep('parent');
388 $this->assertTrue($child->load($cid));
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']));
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());
401 $this->assertTrue($ctransaction->canShow($this->login
));
404 $this->login
->logOut();
405 $this->assertFalse($this->login
->isLogged());
413 public function testTransaction(): void
415 $this->logSuperAdmin();
416 $this->getMemberOne();
417 //create transaction for member
418 $this->createTransaction();
421 $tid = $this->transaction
->id
;
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
428 $edate = clone $bdate;
429 $edate->add(new \
DateInterval('P1Y'));
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
442 $contrib = $this->createContrib($data);
443 $contribs_ids[] = $contrib->id
;
445 $this->assertTrue($contrib->isTransactionPart());
446 $this->assertTrue($contrib->isTransactionPartOf($this->transaction
->id
));
450 $this->transaction
->getDispatchedAmount()
454 $this->transaction
->getMissingAmount()
456 $this->assertSame('transaction-uncomplete', $this->transaction
->getRowClass());
458 //complete the transaction
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
470 $contrib = $this->createContrib($data);
471 $contribs_ids[] = $contrib->id
;
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());
482 $this->transaction
->getDispatchedAmount()
486 $this->transaction
->getMissingAmount()
488 $this->assertSame('transaction-normal', $this->transaction
->getRowClass());
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
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);
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));
512 $this->transaction
->getDispatchedAmount()
516 $this->transaction
->getMissingAmount()
518 $this->assertSame('transaction-uncomplete', $this->transaction
->getRowClass());
520 $this->assertTrue($contrib->setTransactionPart($this->zdb
, $tid, $contrib_id));
524 $this->transaction
->getDispatchedAmount()
528 $this->transaction
->getMissingAmount()
530 $this->assertSame('transaction-normal', $this->transaction
->getRowClass());
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));