Overview
Comment:Implement: quick deposit of cheques
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA1: 2b6dc32a675a857f74e4a186362ecde95dcbbd24
User & Date: bohwaz on 2020-10-15 14:39:54
Other Links: branch diff | manifest | tags
Context
2020-10-16
01:13
Implementation start of graphs check-in: 9b0d5d20d0 user: bohwaz tags: dev
2020-10-15
14:39
Implement: quick deposit of cheques check-in: 2b6dc32a67 user: bohwaz tags: dev
12:49
Fix: use default instead of value in input widgets check-in: 705e128caf user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Accounting/Transactions.php from [89df683976] to [f4ffbb7df1].

1
2
3
4

5
6
7
8
9
10
11
<?php

namespace Garradin\Accounting;


use Garradin\Entities\Accounting\Transaction;
use KD2\DB\EntityManager;
use Garradin\DB;

class Transactions
{
	static public function get(int $id)




>







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

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Line;
use Garradin\Entities\Accounting\Transaction;
use KD2\DB\EntityManager;
use Garradin\DB;

class Transactions
{
	static public function get(int $id)
34
35
36
37
38
39
40



































41
42
43
44
45
46
47
48
49
50
51
			$st->bindValue(':id', (int)$row->id_line, \SQLITE3_INTEGER);
			$st->bindValue(':r', !empty($checked[$row->id_line]) ? 1 : 0, \SQLITE3_INTEGER);
			$st->execute();
		}

		$db->commit();
	}




































	static public function countForUser(int $user_id): int
	{
		return DB::getInstance()->count('acc_transactions_users', 'id_user = ?', $user_id);
	}

	static public function countForCreator(int $user_id): int
	{
		return DB::getInstance()->count('acc_transactions', 'id_creator = ?', $user_id);
	}
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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
83
84
85
86
87
			$st->bindValue(':id', (int)$row->id_line, \SQLITE3_INTEGER);
			$st->bindValue(':r', !empty($checked[$row->id_line]) ? 1 : 0, \SQLITE3_INTEGER);
			$st->execute();
		}

		$db->commit();
	}

	static public function saveDeposit(Transaction $transaction, \Generator $journal, array $checked)
	{
		$db = DB::getInstance();
		$db->begin();

		try {
			$ids = [];
			foreach ($journal as $row) {
				if (!array_key_exists($row->id, $checked)) {
					continue;
				}

				$ids[] = (int)$row->id;

				$line = new Line;
				$line->importForm([
					'reference'  => $row->line_reference,
					'id_account' => $row->id_account,
				]);
				$line->credit = $row->debit;

				$transaction->add($line);
			}

			$transaction->save();
			$ids = implode(',', $ids);
			$db->exec(sprintf('UPDATE acc_transactions SET status = (status | %d) WHERE id IN (%s);', Transaction::STATUS_DEPOSIT, $ids));
			$db->commit();
		}
		catch (\Exception $e) {
			$db->rollback();
			throw $e;
		}
	}

	static public function countForUser(int $user_id): int
	{
		return DB::getInstance()->count('acc_transactions_users', 'id_user = ?', $user_id);
	}

	static public function countForCreator(int $user_id): int
	{
		return DB::getInstance()->count('acc_transactions', 'id_creator = ?', $user_id);
	}
}

Modified src/include/lib/Garradin/Entities/Accounting/Account.php from [b296019730] to [c0c34a0207].

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
			$row->running_sum = $sum;
			$row->date = \DateTime::createFromFormat('Y-m-d', $row->date);
		}

		return $rows;
	}

	public function getReconcileJournal(int $year_id, DateTimeInterface $start_date, DateTimeInterface $end_date, int &$start_sum, int &$end_sum)
	{
		if ($end_date < $start_date) {
			throw new ValidationException('La date de début ne peut être avant la date de fin.');
		}

		$db = DB::getInstance();
		$sql = 'SELECT l.debit, l.credit, t.id, t.date, t.reference, l.reference AS line_reference, t.label, l.label AS line_label, l.reconciled, l.id AS id_line







|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
			$row->running_sum = $sum;
			$row->date = \DateTime::createFromFormat('Y-m-d', $row->date);
		}

		return $rows;
	}

	public function getReconcileJournal(int $year_id, DateTimeInterface $start_date, DateTimeInterface $end_date)
	{
		if ($end_date < $start_date) {
			throw new ValidationException('La date de début ne peut être avant la date de fin.');
		}

		$db = DB::getInstance();
		$sql = 'SELECT l.debit, l.credit, t.id, t.date, t.reference, l.reference AS line_reference, t.label, l.label AS line_label, l.reconciled, l.id AS id_line
168
169
170
171
172
173
174


















175
176
177
178
179
180
181
			$row->running_sum = $sum;

			yield $row;
		}

		yield ['sum' => $sum, 'date' => $end_date];
	}



















	public function getSumAtDate(int $year_id, DateTimeInterface $date): int
	{
		return (int) DB::getInstance()->firstColumn('SELECT SUM(l.credit) - SUM(l.debit)
			FROM acc_transactions_lines l
			INNER JOIN acc_transactions t ON t.id = l.id_transaction
			wHERE l.id_account = ? AND t.id_year = ? AND t.date < ?







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
			$row->running_sum = $sum;

			yield $row;
		}

		yield ['sum' => $sum, 'date' => $end_date];
	}

	public function getDepositJournal(int $year_id): \Generator
	{
		$res = DB::getInstance()->iterate('SELECT l.debit, l.credit, t.id, t.date, t.reference, l.reference AS line_reference, t.label, l.label AS line_label, l.reconciled, l.id AS id_line, l.id_account
			FROM acc_transactions_lines l
			INNER JOIN acc_transactions t ON t.id = l.id_transaction
			WHERE t.id_year = ? AND l.id_account = ? AND l.credit = 0 AND NOT (t.status & ?);',
			$year_id, $this->id(), Transaction::STATUS_DEPOSIT);

		$sum = 0;

		foreach ($res as $row) {
			$row->date = \DateTime::createFromFormat('Y-m-d', $row->date);
			$sum += ($row->credit - $row->debit);
			$row->running_sum = $sum;
			yield $row;
		}
	}

	public function getSumAtDate(int $year_id, DateTimeInterface $date): int
	{
		return (int) DB::getInstance()->firstColumn('SELECT SUM(l.credit) - SUM(l.debit)
			FROM acc_transactions_lines l
			INNER JOIN acc_transactions t ON t.id = l.id_transaction
			wHERE l.id_account = ? AND t.id_year = ? AND t.date < ?

Modified src/include/lib/Garradin/Entities/Accounting/Transaction.php from [02e2fdcd8b] to [d109570628].

21
22
23
24
25
26
27

28
29
30
31
32
33
34
	const TYPE_TRANSFER = 3;
	const TYPE_DEBT = 4;
	const TYPE_CREDIT = 5;
	const TYPE_PAYOFF = 6;

	const STATUS_WAITING = 1;
	const STATUS_PAID = 2;


	const TYPES_NAMES = [
		'Avancé',
		'Recette',
		'Dépense',
		'Virement',
		'Dette',







>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
	const TYPE_TRANSFER = 3;
	const TYPE_DEBT = 4;
	const TYPE_CREDIT = 5;
	const TYPE_PAYOFF = 6;

	const STATUS_WAITING = 1;
	const STATUS_PAID = 2;
	const STATUS_DEPOSIT = 4;

	const TYPES_NAMES = [
		'Avancé',
		'Recette',
		'Dépense',
		'Virement',
		'Dette',
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
























248
249
250
251
252
253
254
255

		foreach ($lines as $line) {
			$total += $line->credit;
			$total -= $line->debit;
		}

		if (0 !== $total) {
			throw new ValidationException('Écriture non équilibrée : déséquilibre entre débits et crédits');
		}

		if (!array_key_exists($this->type, self::TYPES_NAMES)) {
			throw new ValidationException('Type d\'écriture inconnu');
		}
	}

























	public function importFromNewForm(int $chart_id, ?array $source = null): void
	{
		if (null === $source) {
			$source = $_POST;
		}

		if (empty($source['type'])) {
			throw new ValidationException('Type d\'écriture inconnu');







|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

		foreach ($lines as $line) {
			$total += $line->credit;
			$total -= $line->debit;
		}

		if (0 !== $total) {
			throw new ValidationException(sprintf('Écriture non équilibrée : déséquilibre (%s) entre débits et crédits', Utils::money_format($total)));
		}

		if (!array_key_exists($this->type, self::TYPES_NAMES)) {
			throw new ValidationException('Type d\'écriture inconnu');
		}
	}

	public function importFromDepositForm(?array $source = null): void
	{
		if (null === $source) {
			$source = $_POST;
		}

		$this->type = self::TYPE_TRANSFER;
		$amount = $source['amount'];

		$key = 'account_transfer';
		$account = isset($source[$key]) && @count($source[$key]) ? key($source[$key]) : null;

		$line = new Line;
		$line->importForm([
			'debit'      => $amount,
			'credit'     => 0,
			'id_account' => $account,
		]);

		$this->add($line);

		$this->importForm($source);
	}

	public function importFromNewForm(?array $source = null): void
	{
		if (null === $source) {
			$source = $_POST;
		}

		if (empty($source['type'])) {
			throw new ValidationException('Type d\'écriture inconnu');

Modified src/include/lib/Garradin/Template.php from [a556e64691] to [838003c89e].

302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
				$current_value = Utils::money_format($current_value, ',', '');
			}

			$currency = Config::getInstance()->get('monnaie');
			$input = sprintf('<input type="text" pattern="[0-9]*([.,][0-9]{1,2})?" inputmode="decimal" size="8" class="money" %s value="%s" /><b>%s</b>', $attributes_string, $this->escape($current_value), $currency);
		}
		else {

			$input = sprintf('<input type="%s" %s value="%s" />', $type, $attributes_string, $this->escape($current_value));
		}

		// No label? then we only want the input without the widget
		if (empty($label)) {
			return $input;
		}








>
|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
				$current_value = Utils::money_format($current_value, ',', '');
			}

			$currency = Config::getInstance()->get('monnaie');
			$input = sprintf('<input type="text" pattern="[0-9]*([.,][0-9]{1,2})?" inputmode="decimal" size="8" class="money" %s value="%s" /><b>%s</b>', $attributes_string, $this->escape($current_value), $currency);
		}
		else {
			$value = isset($attributes['value']) ? '' : sprintf(' value="%s"', $this->escape($current_value));
			$input = sprintf('<input type="%s" %s %s />', $type, $attributes_string, $value);
		}

		// No label? then we only want the input without the widget
		if (empty($label)) {
			return $input;
		}

Added src/templates/acc/accounts/deposit.tpl version [981f4f25b1].

































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
{include file="admin/_head.tpl" title="Dépôt en banque : %s — %s"|args:$account.code,$account.label current="acc/accounts" js=1}

<p class="help">
	Cocher les cases correspondant aux montants à déposer, une nouvelle écriture sera générée.
</p>

{form_errors}

<form method="post" action="{$self_url}">
	<table class="list">
		<thead>
			<tr>
				<td class="check"><input type="checkbox" title="Tout cocher / décocher" /></td>
				<td></td>
				<td>Date</td>
				<td>Réf. écriture</td>
				<td>Réf. ligne</td>
				<th>Libellé</th>
				<td class="money">Montant</td>
				<td class="money">Solde cumulé</td>
			</tr>
		</thead>
		<tbody>
			{foreach from=$journal item="line"}
			{if isset($line.sum)}
			<tr>
				<td colspan="5"></td>
				<td class="money">{if $line.sum > 0}-{/if}{$line.sum|abs|raw|html_money:false}</td>
				<th>Solde au {$line.date|date_fr:'d/m/Y'}</th>
				<td colspan="2"></td>
			</tr>
			{else}
			<tr>
				<td class="check"><input type="checkbox" name="deposit[{$line.id}]" value="1" data-debit="{$line.debit}" data-credit="{$line.credit}" /></td>
				<td class="num"><a href="{$admin_url}acc/transactions/details.php?id={$line.id}">#{$line.id}</a></td>
				<td>{$line.date|date_fr:'d/m/Y'}</td>
				<td>{$line.reference}</td>
				<td>{$line.line_reference}</td>
				<th>{$line.label}</th>
				<td class="money">{$line.debit|raw|html_money}</td> {* Not a bug! Credit/debit is reversed here to reflect the bank statement *}
				<td class="money">{if $line.running_sum > 0}-{/if}{$line.running_sum|abs|raw|html_money:false}</td>
			</tr>
			{/if}
		{/foreach}
		</tbody>
	</table>

	<fieldset>
		<legend>Détails de l'écriture de dépôt</legend>
		<dl>
			{input type="text" name="label" label="Libellé" required=1 default="Dépôt en banque"}
			{input type="date" name="date" default=$date label="Date" required=1}
			{input type="money" name="amount" label="Montant" required=1}
			{input type="list" target="acc/charts/accounts/selector.php?chart=%d&targets=%d"|args:$account.id_chart,$target name="account_transfer" label="Compte de dépôt" required=1}
			{input type="text" name="reference" label="Numéro de pièce comptable"}
			{input type="textarea" name="notes" label="Remarques" rows=4 cols=30}
		</dl>
	</fieldset>

	<p class="submit">
		{csrf_field key="acc_deposit_%s"|args:$account.id}
		<input type="submit" name="save" value="Enregistrer le dépôt &rarr;" />
	</p>
</form>

{literal}
<script type="text/javascript">
var total = 0;
$('tbody input[type=checkbox]').forEach((e) => {
	e.addEventListener('change', () => {
		var v = e.getAttribute('data-debit') || e.getAttribute('data-credit');
		v = parseInt(v, 10);
		total += e.checked ? v : -v;
		$('#f_amount').value = g.formatMoney(total);
	});
});
</script>
{/literal}

{include file="admin/_foot.tpl"}

Modified src/templates/acc/accounts/index.tpl from [c0634827f4] to [dcc06b4c3f].

38
39
40
41
42
43
44

45
46



47
48
49
50
51
52
53
						{$account.sum|abs|raw|html_money:false}&nbsp;{$config.monnaie}
					{else}
						{$account.sum|raw|html_money:false}&nbsp;{$config.monnaie}
					{/if}
				</td>
				<td class="actions">
					{linkbutton label="Journal" shape="menu" href="acc/accounts/journal.php?id=%d&year=%d"|args:$account.id,$current_year.id}

					{if $account.type == Entities\Accounting\Account::TYPE_BANK && $session->canAccess('compta', Membres::DROIT_ADMIN)}
						{linkbutton label="Rapprocher" shape="check" href="acc/accounts/reconcile.php?id=%d"|args:$account.id}



					{/if}
				</td>
			</tr>
		{/foreach}
	</tbody>
	{/foreach}
</table>







>
|
|
>
>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
						{$account.sum|abs|raw|html_money:false}&nbsp;{$config.monnaie}
					{else}
						{$account.sum|raw|html_money:false}&nbsp;{$config.monnaie}
					{/if}
				</td>
				<td class="actions">
					{linkbutton label="Journal" shape="menu" href="acc/accounts/journal.php?id=%d&year=%d"|args:$account.id,$current_year.id}
					{if $session->canAccess('compta', Membres::DROIT_ADMIN)}
						{if $account.type == Entities\Accounting\Account::TYPE_BANK}
							{linkbutton label="Rapprocher" shape="check" href="acc/accounts/reconcile.php?id=%d"|args:$account.id}
						{elseif $account.type == Entities\Accounting\Account::TYPE_OUTSTANDING}
							{linkbutton label="Dépôt en banque" shape="check" href="acc/accounts/deposit.php?id=%d"|args:$account.id}
						{/if}
					{/if}
				</td>
			</tr>
		{/foreach}
	</tbody>
	{/foreach}
</table>

Modified src/templates/acc/accounts/reconcile.tpl from [823d2348a3] to [29c73c04df].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
			<input type="submit" value="Afficher" />
		</p>
	</fieldset>
</form>

<p class="alert">
	<strong>Attention&nbsp;!</strong>
	Les écritures apparaissent ici dans le sens de la banque, à l'inverse des journaux comptables.
</p>

{form_errors}

<form method="post" action="{$self_url}">
	<table class="list">
		<thead>







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
			<input type="submit" value="Afficher" />
		</p>
	</fieldset>
</form>

<p class="alert">
	<strong>Attention&nbsp;!</strong>
	Afin de simplifier les choses, les écritures apparaissent ici dans le sens de la banque, à l'inverse des journaux comptables.
</p>

{form_errors}

<form method="post" action="{$self_url}">
	<table class="list">
		<thead>

Modified src/templates/acc/transactions/new.tpl from [a144607242] to [1b39cbd3bf].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
				{input type="list" target="%sacc/charts/accounts/selector.php?targets=%s&chart=%d"|args:$admin_url,$payoff_targets,$chart_id name="account_payoff" label="Compte de règlement" required=1}
			</dl>
		</fieldset>
	{else}
		<fieldset>
			<legend>Type d'écriture</legend>
			<dl>
				{input type="radio" name="type" value=$transaction::TYPE_REVENUE label="Recette"}
				{input type="radio" name="type" value=$transaction::TYPE_EXPENSE label="Dépense"}
				{input type="radio" name="type" value=$transaction::TYPE_TRANSFER label="Virement" help="Faire un virement entre comptes, déposer des espèces en banque, etc."}
				{input type="radio" name="type" value=$transaction::TYPE_DEBT label="Dette" help="Quand l'association doit de l'argent à un membre ou un fournisseur"}
				{input type="radio" name="type" value=$transaction::TYPE_CREDIT label="Créance" help="Quand un membre ou un fournisseur doit de l'argent à l'association"}
				{input type="radio" name="type" value=$transaction::TYPE_ADVANCED label="Saisie avancée" help="Choisir les comptes du plan comptable, ventiler une écriture sur plusieurs comptes, etc."}
			</dl>
		</fieldset>

		{foreach from=$types item="type"}
			<fieldset data-types="t{$type.id}">
				<legend>{$type.label}</legend>
				<dl>







|
|
|
|
|
|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
				{input type="list" target="%sacc/charts/accounts/selector.php?targets=%s&chart=%d"|args:$admin_url,$payoff_targets,$chart_id name="account_payoff" label="Compte de règlement" required=1}
			</dl>
		</fieldset>
	{else}
		<fieldset>
			<legend>Type d'écriture</legend>
			<dl>
				{input type="radio" name="type" value=$transaction::TYPE_REVENUE default=-1 label="Recette"}
				{input type="radio" name="type" value=$transaction::TYPE_EXPENSE default=-1 label="Dépense"}
				{input type="radio" name="type" value=$transaction::TYPE_TRANSFER default=-1 label="Virement" help="Faire un virement entre comptes, déposer des espèces en banque, etc."}
				{input type="radio" name="type" value=$transaction::TYPE_DEBT default=-1 label="Dette" help="Quand l'association doit de l'argent à un membre ou un fournisseur"}
				{input type="radio" name="type" value=$transaction::TYPE_CREDIT default=-1 label="Créance" help="Quand un membre ou un fournisseur doit de l'argent à l'association"}
				{input type="radio" name="type" value=$transaction::TYPE_ADVANCED default=-1 label="Saisie avancée" help="Choisir les comptes du plan comptable, ventiler une écriture sur plusieurs comptes, etc."}
			</dl>
		</fieldset>

		{foreach from=$types item="type"}
			<fieldset data-types="t{$type.id}">
				<legend>{$type.label}</legend>
				<dl>

Added src/www/admin/acc/accounts/deposit.php version [6e7b17b57a].















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
namespace Garradin;

use Garradin\Accounting\Accounts;
use Garradin\Accounting\Transactions;
use Garradin\Entities\Accounting\Transaction;

require_once __DIR__ . '/../_inc.php';

$session->requireAccess('compta', Membres::DROIT_ADMIN);

$account = Accounts::get((int)qg('id'));

if (!$account) {
	throw new UserException("Le compte demandé n'existe pas.");
}

$journal = $account->getDepositJournal(CURRENT_YEAR_ID);
$transaction = new Transaction;
$transaction->id_year = CURRENT_YEAR_ID;

$rules = [
	'deposit' => 'array',
];

// Enregistrement des cases cochées
if (f('save') && $form->check('acc_deposit_' . $account->id, $rules))
{
	try {
		$transaction->importFromDepositForm();
		Transactions::saveDeposit($transaction, $journal, f('deposit'));
		Utils::redirect(ADMIN_URL . 'acc/transactions/details.php?id=' . $transaction->id());
	}
	catch (UserException $e) {
		$journal = $account->getDepositJournal(CURRENT_YEAR_ID);
		$form->addError($e->getMessage());
	}
}

$date = new \DateTime;

if ($date > $current_year->end_date) {
	$date = $current_year->end_date;
}

$target = $account::TYPE_BANK;

$tpl->assign(compact(
	'account',
	'journal',
	'date',
	'target'
));

$tpl->display('acc/accounts/deposit.tpl');

Modified src/www/admin/acc/accounts/reconcile.php from [6821b3b7e5] to [23ea2afcaf].

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
if ($start < $current_year->start_date || $start > $current_year->end_date
	|| $end < $current_year->start_date || $end > $current_year->end_date) {
	$start = clone $current_year->start_date;
	$end = clone $start;
	$end->modify('last day of this month');
}

$start_sum = 0;$end_sum = 0;
$journal = $account->getReconcileJournal(CURRENT_YEAR_ID, $start, $end, $start_sum, $end_sum);

// Enregistrement des cases cochées
if ((f('save') || f('save_next')) && $form->check('acc_reconcile_' . $account->id))
{
	try {
		Transactions::saveReconciled($journal, f('reconcile'));








<
|







35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
if ($start < $current_year->start_date || $start > $current_year->end_date
	|| $end < $current_year->start_date || $end > $current_year->end_date) {
	$start = clone $current_year->start_date;
	$end = clone $start;
	$end->modify('last day of this month');
}


$journal = $account->getReconcileJournal(CURRENT_YEAR_ID, $start, $end);

// Enregistrement des cases cochées
if ((f('save') || f('save_next')) && $form->check('acc_reconcile_' . $account->id))
{
	try {
		Transactions::saveReconciled($journal, f('reconcile'));

74
75
76
77
78
79
80
81
82
83
84
	'start',
	'end',
	'prev',
	'next',
	'journal',
));

$tpl->assign_by_ref('start_sum', $start_sum);
$tpl->assign_by_ref('end_sum', $end_sum);

$tpl->display('acc/accounts/reconcile.tpl');







<
<
<

73
74
75
76
77
78
79



80
	'start',
	'end',
	'prev',
	'next',
	'journal',
));




$tpl->display('acc/accounts/reconcile.tpl');

Modified src/www/admin/acc/transactions/new.php from [52c4d14451] to [a9db35407e].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
	$payoff_for = $transaction->payOffFrom($id);
	$amount = $payoff_for->sum();
}

if (f('save') && $form->check('acc_transaction_new')) {
	try {
		$transaction->id_year = $current_year->id();
		$transaction->importFromNewForm($chart->id());
		$transaction->id_creator = $session->getUser()->id;
		$transaction->save();

		// Append file
		if (!empty($_FILES['file']['name'])) {
			$file = Fichiers::upload($_FILES['file']);
			$file->linkTo(Fichiers::LIEN_COMPTA, $transaction->id());







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
	$payoff_for = $transaction->payOffFrom($id);
	$amount = $payoff_for->sum();
}

if (f('save') && $form->check('acc_transaction_new')) {
	try {
		$transaction->id_year = $current_year->id();
		$transaction->importFromNewForm();
		$transaction->id_creator = $session->getUser()->id;
		$transaction->save();

		// Append file
		if (!empty($_FILES['file']['name'])) {
			$file = Fichiers::upload($_FILES['file']);
			$file->linkTo(Fichiers::LIEN_COMPTA, $transaction->id());

Modified src/www/admin/static/scripts/accounting.js from [0075f54b09] to [52244ec66b].

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

		if (m = $('#lines_message')) {
			m.innerHTML = (debit === credit) ? '' : '<span class="alert">Écriture non équilibrée</span>';
		}

		debit = debit ? debit + '' : '000';
		credit = credit ? credit + '' : '000';
		$('#f_debit_total').value = (debit.substr(0, debit.length-2) || '0') + ',' + debit.substr(-2);
		$('#f_credit_total').value = (credit.substr(0, credit.length-2) || '0') + ',' + credit.substr(-2);
	}

	// Add row button
	$('.transaction-lines tfoot button')[0].onclick = () => {
		var line = $('.transaction-lines tbody tr')[0];
		var n = line.cloneNode(true);
		n.querySelectorAll('input').forEach((e) => {







|
|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

		if (m = $('#lines_message')) {
			m.innerHTML = (debit === credit) ? '' : '<span class="alert">Écriture non équilibrée</span>';
		}

		debit = debit ? debit + '' : '000';
		credit = credit ? credit + '' : '000';
		$('#f_debit_total').value = g.formatMoney(debit);
		$('#f_credit_total').value = g.formatMoney(credit);
	}

	// Add row button
	$('.transaction-lines tfoot button')[0].onclick = () => {
		var line = $('.transaction-lines tbody tr')[0];
		var n = line.cloneNode(true);
		n.querySelectorAll('input').forEach((e) => {

Modified src/www/admin/static/scripts/global.js from [830dad5a1e] to [dc757df630].

234
235
236
237
238
239
240





241
242
243
244
245
246
247
			i.removeChild(old);
		}

		i.appendChild(span);
		g.closeDialog();
		i.firstChild.focus();
	};






	// Sélecteurs de listes
	g.onload(() => {
		var inputs = $('form .input-list > button');

		inputs.forEach((i) => {
			i.onclick = () => {







>
>
>
>
>







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
			i.removeChild(old);
		}

		i.appendChild(span);
		g.closeDialog();
		i.firstChild.focus();
	};

	g.formatMoney = (v) => {
		v = '' + v;
		return (v.substr(0, v.length-2) || '0') + ',' + (v + '00').substr(-2);
	};

	// Sélecteurs de listes
	g.onload(() => {
		var inputs = $('form .input-list > button');

		inputs.forEach((i) => {
			i.onclick = () => {