Overview
Comment:Fix small issues and inconsistencies after refactoring of transaction code
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 863d48d3ba7d3410e1f5400a8caf752b076070e05a8eeb27ab1f376e4bedfc4d
User & Date: bohwaz on 2022-07-30 17:41:55
Other Links: manifest | tags
Context
2022-07-30
18:23
Remove _form_rules feature in entities, improve and fix bugs in account add from transaction check-in: 4e2775ba8e user: bohwaz tags: trunk, stable
17:41
Fix small issues and inconsistencies after refactoring of transaction code check-in: 863d48d3ba user: bohwaz tags: trunk
15:44
Refactor quick transactions and balance check-in: 9a87c42d0b user: bohwaz tags: trunk
Changes

Modified src/include/lib/Garradin/Accounting/Accounts.php from [cdc87c01aa] to [af4b257ad1].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
	}

	static public function getSelectorLabel(int $id)
	{
		return EntityManager::getInstance(Account::class)->col('SELECT code || \' — \' || label FROM @TABLE WHERE id = ?;', $id);
	}

	static public function getIdFromCode(string $code): int
	{
		return $this->em->col('SELECT id FROM @TABLE WHERE code = ? AND id_chart = ?;', $code, $this->chart_id);
	}

	static public function getCodeFromId(string $id): string
	{
		return EntityManager::getInstance(Account::class)->col('SELECT code FROM @TABLE WHERE id = ?;', $id);







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
	}

	static public function getSelectorLabel(int $id)
	{
		return EntityManager::getInstance(Account::class)->col('SELECT code || \' — \' || label FROM @TABLE WHERE id = ?;', $id);
	}

	public function getIdFromCode(string $code): int
	{
		return $this->em->col('SELECT id FROM @TABLE WHERE code = ? AND id_chart = ?;', $code, $this->chart_id);
	}

	static public function getCodeFromId(string $id): string
	{
		return EntityManager::getInstance(Account::class)->col('SELECT code FROM @TABLE WHERE id = ?;', $id);

Modified src/include/lib/Garradin/Entities/Accounting/Line.php from [cca7640817] to [c93ddb30c0].

58
59
60
61
62
63
64



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
		$value = parent::filterUserValue($type, $value, $key);

		return $value;
	}

	public function selfCheck(): void
	{



		$this->assert($this->reference === null || strlen($this->reference) < 200, 'La référence doit faire moins de 200 caractères.');
		$this->assert($this->label === null || strlen($this->label) < 200, 'La référence doit faire moins de 200 caractères.');
		$this->assert($this->id_account !== null, 'Aucun compte n\'a été indiqué.');
		$this->assert($this->credit || $this->debit, 'Aucun montant au débit ou au crédit');
		$this->assert($this->credit >= 0 && $this->debit >= 0, 'Le montant ne peut être négatif');
		$this->assert(($this->credit * $this->debit) === 0 && ($this->credit + $this->debit) > 0, 'Ligne non équilibrée : crédit ou débit doit valoir zéro.');
		$this->assert($this->reconciled === 0 || $this->reconciled === 1);
		$this->assert(DB::getInstance()->test(Account::TABLE, 'id = ?', $this->id_account), 'Le compte indiqué n\'existe pas.');
		// The fact that the account is in the right chart is checked in Transaction::selfCheck
		$this->assert(null === $this->id_analytical || DB::getInstance()->test(Account::TABLE, 'id = ?', $this->id_analytical), 'Le projet analytique indiqué n\'existe pas.');
		$this->assert(!empty($this->id_transaction), 'Aucune écriture n\'a été indiquée pour cette ligne.');
		parent::selfCheck();
	}

	public function asDetailsArray(): array
	{







>
>
>







|
<







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
		$value = parent::filterUserValue($type, $value, $key);

		return $value;
	}

	public function selfCheck(): void
	{
		// We don't check that the account exists here
		// The fact that the account is in the right chart is checked in Transaction::selfCheck

		$this->assert($this->reference === null || strlen($this->reference) < 200, 'La référence doit faire moins de 200 caractères.');
		$this->assert($this->label === null || strlen($this->label) < 200, 'La référence doit faire moins de 200 caractères.');
		$this->assert($this->id_account !== null, 'Aucun compte n\'a été indiqué.');
		$this->assert($this->credit || $this->debit, 'Aucun montant au débit ou au crédit');
		$this->assert($this->credit >= 0 && $this->debit >= 0, 'Le montant ne peut être négatif');
		$this->assert(($this->credit * $this->debit) === 0 && ($this->credit + $this->debit) > 0, 'Ligne non équilibrée : crédit ou débit doit valoir zéro.');
		$this->assert($this->reconciled === 0 || $this->reconciled === 1);


		$this->assert(null === $this->id_analytical || DB::getInstance()->test(Account::TABLE, 'id = ?', $this->id_analytical), 'Le projet analytique indiqué n\'existe pas.');
		$this->assert(!empty($this->id_transaction), 'Aucune écriture n\'a été indiquée pour cette ligne.');
		parent::selfCheck();
	}

	public function asDetailsArray(): array
	{
110
111
112
113
114
115
116



117
118
119
120
121
122
123
124
125
126
			$source['id_account'] = (int)key($source['account_selector']);
		}
		elseif (isset($source['account'])) {
			if (empty($source['account']) || is_array($source['account'])) {
				throw new ValidationException('Aucun compte n\'a été choisi.');
			}




			$source['account'] = Accounts::getIdFromCode($source['account']);

			if (empty($source['account'])) {
				throw new ValidationException('Le compte choisi n\'existe pas.');
			}
		}

		return parent::importForm($source);
	}
}







>
>
>
|









112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
			$source['id_account'] = (int)key($source['account_selector']);
		}
		elseif (isset($source['account'])) {
			if (empty($source['account']) || is_array($source['account'])) {
				throw new ValidationException('Aucun compte n\'a été choisi.');
			}

			// Find id from code
			// We don't check that the account belongs to the correct chart for the year of the linked transaction here
			// It is done in Transaction->selfCheck()
			$source['account'] = DB::getInstance()->firstColumn('SELECT id FROM acc_accounts WHERE code = ?;', $source['account']);

			if (empty($source['account'])) {
				throw new ValidationException('Le compte choisi n\'existe pas.');
			}
		}

		return parent::importForm($source);
	}
}

Modified src/include/lib/Garradin/Entities/Accounting/Transaction.php from [70e76e55ab] to [b5639ed20f].

432
433
434
435
436
437
438




439
440
441
442
443
444
445

		$lines = $this->getLinesWithAccounts();

		// Self check lines before saving Transaction
		foreach ($lines as $i => $l) {
			$line = $l->line;
			$line->id_transaction = -1; // Get around validation of id_transaction being not null





			if ($this->type == self::TYPE_EXPENSE && $l->account_position == Account::REVENUE) {
				throw new ValidationException('Il n\'est pas possible d\'attribuer un compte de produit à une dépense');
			}

			if ($this->type == self::TYPE_REVENUE && $l->account_position == Account::EXPENSE) {
				throw new ValidationException('Il n\'est pas possible d\'attribuer un compte de dépense à une recette');







>
>
>
>







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

		$lines = $this->getLinesWithAccounts();

		// Self check lines before saving Transaction
		foreach ($lines as $i => $l) {
			$line = $l->line;
			$line->id_transaction = -1; // Get around validation of id_transaction being not null

			if (empty($l->account_code)) {
				throw new ValidationException('Le compte spécifié n\'existe pas.');
			}

			if ($this->type == self::TYPE_EXPENSE && $l->account_position == Account::REVENUE) {
				throw new ValidationException('Il n\'est pas possible d\'attribuer un compte de produit à une dépense');
			}

			if ($this->type == self::TYPE_REVENUE && $l->account_position == Account::EXPENSE) {
				throw new ValidationException('Il n\'est pas possible d\'attribuer un compte de dépense à une recette');

Modified src/templates/acc/transactions/_lines_form.tpl from [4281f7cc10] to [bb94f0b609].

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
<?php
assert(is_array($lines));
assert(is_array($analytical_accounts));
assert(!isset($lines_accounts) || is_array($lines_accounts));
?>

<table class="list transaction-lines">
	<thead>
		<tr>
			<td>Compte</td>
			<td>Débit</td>
			<td>Crédit</td>
			<td>Réf. ligne</td>
			<td>Libellé ligne</td>

			{if count($analytical_accounts) > 1}
				<td>Projet</td>
			{/if}
			<td></td>
		</tr>
	</thead>
	<tbody>
	{foreach from=$lines key="k" item="line"}
		<tr>
			<td class="account">
				{input type="list" target="!acc/charts/accounts/selector.php?chart=%d"|args:$chart_id name="lines[account_selector][]" default=$line.account_selector}
			</td>
			<td class="money">{input type="money" name="lines[debit][]" default=$line.debit size=5}</td>
			<td class="money">{input type="money" name="lines[credit][]" default=$line.credit size=5}</td>
			<td>{input type="text" name="lines[reference][]" default=$line.reference size=10}</td>
			<td>{input type="text" name="lines[label][]" default=$line.label}</td>

			{if count($analytical_accounts) > 1}
				<td>{input default=$line.id_analytical type="select" name="lines[id_analytical][]" options=$analytical_accounts}</td>
			{/if}
			<td>{button label="Enlever" title="Enlever la ligne" shape="minus" min="2" name="remove_line"}</td>
		</tr>
	{/foreach}
	</tbody>












<

>














<

>







1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
<?php
assert(is_array($lines));
assert(is_array($analytical_accounts));
assert(!isset($lines_accounts) || is_array($lines_accounts));
?>

<table class="list transaction-lines">
	<thead>
		<tr>
			<td>Compte</td>
			<td>Débit</td>
			<td>Crédit</td>

			<td>Libellé ligne</td>
			<td>Réf. ligne</td>
			{if count($analytical_accounts) > 1}
				<td>Projet</td>
			{/if}
			<td></td>
		</tr>
	</thead>
	<tbody>
	{foreach from=$lines key="k" item="line"}
		<tr>
			<td class="account">
				{input type="list" target="!acc/charts/accounts/selector.php?chart=%d"|args:$chart_id name="lines[account_selector][]" default=$line.account_selector}
			</td>
			<td class="money">{input type="money" name="lines[debit][]" default=$line.debit size=5}</td>
			<td class="money">{input type="money" name="lines[credit][]" default=$line.credit size=5}</td>

			<td>{input type="text" name="lines[label][]" default=$line.label}</td>
			<td>{input type="text" name="lines[reference][]" default=$line.reference size=10}</td>
			{if count($analytical_accounts) > 1}
				<td>{input default=$line.id_analytical type="select" name="lines[id_analytical][]" options=$analytical_accounts}</td>
			{/if}
			<td>{button label="Enlever" title="Enlever la ligne" shape="minus" min="2" name="remove_line"}</td>
		</tr>
	{/foreach}
	</tbody>