Overview
Comment:Also use the new CSV_Custom class in year import
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev | 1.0.0-beta6
Files: files | file ages | folders
SHA1: 9ae436aa00a67492da7b97dae518a1d9d227c036
User & Date: bohwaz on 2020-11-19 20:52:18
Other Links: branch diff | manifest | tags
Context
2020-11-20
11:25
Fix font size check-in: a2cf0f7138 user: bohwaz tags: dev
2020-11-19
20:52
Also use the new CSV_Custom class in year import check-in: 9ae436aa00 user: bohwaz tags: dev, 1.0.0-beta6
20:50
Allow extra parameters for linkbuttons check-in: aff9dad340 user: bohwaz tags: dev
Changes

Modified src/VERSION from [f219a06531] to [68464799f3].

1
1.0.0-beta5
|
1
1.0.0-beta6

Modified src/include/lib/Garradin/Accounting/Transactions.php from [c500c82e65] to [48a7e2b83b].

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
<?php

namespace Garradin\Accounting;

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

use Garradin\DB;
use Garradin\Utils;
use Garradin\UserException;

class Transactions
{
	const EXPECTED_CSV_COLUMNS_SELF = ['id', 'type', 'status', 'label', 'date', 'notes', 'reference',









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Line;
use Garradin\Entities\Accounting\Transaction;
use Garradin\Entities\Accounting\Year;
use KD2\DB\EntityManager;
use Garradin\CSV;
use Garradin\CSV_Custom;
use Garradin\DB;
use Garradin\Utils;
use Garradin\UserException;

class Transactions
{
	const EXPECTED_CSV_COLUMNS_SELF = ['id', 'type', 'status', 'label', 'date', 'notes', 'reference',
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
			$db->rollback();
			throw new UserException(sprintf('Erreur sur la ligne %d : %s', $l, $e->getMessage()));
		}

		$db->commit();
	}

	static public function importArray(Year $year, array $table, array $translation_table, int $skip_lines, int $user_id)
	{
		if ($year->closed) {
			throw new \InvalidArgumentException('Closed year');
		}

		$db = DB::getInstance();
		$db->begin();

		if ($skip_lines)
		{
			$table = array_slice($table, $skip_lines, null, true);
		}

		$accounts = $year->accounts();
		$l = 0;

		try {
			foreach ($table as $l => $row) {
				$row = (object) array_combine($translation_table, $row);

				if (!isset($row->credit_account, $row->debit_account, $row->amount)) {
					throw new UserException('Une des colonnes compte de crédit, compte de débit ou montant est manquante.');
				}

				if (!empty($row->id)) {
					$transaction = self::get((int)$row->id);








|








<
<
<
<
<




|
<
<







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
			$db->rollback();
			throw new UserException(sprintf('Erreur sur la ligne %d : %s', $l, $e->getMessage()));
		}

		$db->commit();
	}

	static public function importCustom(Year $year, CSV_Custom $csv, int $user_id)
	{
		if ($year->closed) {
			throw new \InvalidArgumentException('Closed year');
		}

		$db = DB::getInstance();
		$db->begin();






		$accounts = $year->accounts();
		$l = 0;

		try {
			foreach ($csv->iterate() as $l => $row) {


				if (!isset($row->credit_account, $row->debit_account, $row->amount)) {
					throw new UserException('Une des colonnes compte de crédit, compte de débit ou montant est manquante.');
				}

				if (!empty($row->id)) {
					$transaction = self::get((int)$row->id);

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
				$fields = array_intersect_key((array)$row, array_flip(['label', 'date', 'notes', 'reference']));
				$transaction->importForm($fields);

				$credit_account = $accounts->getIdFromCode($row->credit_account);
				$debit_account = $accounts->getIdFromCode($row->debit_account);

				if (!$credit_account) {
					throw new UserException('Compte inconnu dans le plan comptable : ' . $row->credit_account);
				}

				if (!$debit_account) {
					throw new UserException('Compte inconnu dans le plan comptable : ' . $row->debit_account);
				}

				$line = new Line;
				$line->importForm([
					'credit'     => $row->amount,
					'debit'      => 0,
					'id_account' => $credit_account,







|



|







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
				$fields = array_intersect_key((array)$row, array_flip(['label', 'date', 'notes', 'reference']));
				$transaction->importForm($fields);

				$credit_account = $accounts->getIdFromCode($row->credit_account);
				$debit_account = $accounts->getIdFromCode($row->debit_account);

				if (!$credit_account) {
					throw new UserException(sprintf('Compte de crédit "%s" inconnu dans le plan comptable', $row->credit_account));
				}

				if (!$debit_account) {
					throw new UserException(sprintf('Compte de débit "%s" inconnu dans le plan comptable', $row->debit_account));
				}

				$line = new Line;
				$line->importForm([
					'credit'     => $row->amount,
					'debit'      => 0,
					'id_account' => $credit_account,

Modified src/include/lib/Garradin/CSV_Custom.php from [530c21f045] to [53c7fd6e8d].

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
		}

		$this->translation = $translation;

		$this->session->set($this->key . '_translation', $this->translation);
	}

	public function cancel(): void
	{
		$this->session->set($this->key, null);
		$this->session->set($this->key . '_translation', null);
		$this->session->set($this->key . '_skip', null);
	}

	public function loaded(): bool







|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
		}

		$this->translation = $translation;

		$this->session->set($this->key . '_translation', $this->translation);
	}

	public function clear(): void
	{
		$this->session->set($this->key, null);
		$this->session->set($this->key . '_translation', null);
		$this->session->set($this->key . '_skip', null);
	}

	public function loaded(): bool

Modified src/include/lib/Garradin/Entities/Accounting/Account.php from [586729a295] to [3b7ef1378b].

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327


328
329
330













331
332
333
334
335
336
337
		$journal = iterator_to_array($journal);
		$i = 0;
		$sum = 0;

		foreach ($csv as $k => &$line) {
			try {
				$date = \DateTime::createFromFormat('!d/m/Y', $line->date);
				$amount = Utils::moneyToInteger($line->amount);

				if (!$date) {
					throw new UserException('Date invalide : ' . $line->date);
				}

				$line->date = $date;
			}
			catch (UserException $e) {
				throw new UserException(sprintf('Ligne %d : %s', $k, $e->getMessage()));
			}

			$line->debit = null;
			$line->credit = null;

			if (substr(trim($line->amount), 0, 1) == '-') {
				$line->debit = $amount;
			}
			else {
				$line->credit = $amount;
			}
		}
		unset($line);

		foreach ($journal as $j) {
			$id = $j->date->format('Ymd') . '.' . $i++;

			$row = (object) ['csv' => null, 'journal' => $j];

			if (isset($j->debit)) {
				foreach ($csv as &$line) {
					if (!isset($line->date)) {
						 continue;
					}
					if ($j->date->format('Ymd') == $line->date->format('Ymd')
						&& ($j->credit == $line->debit || $j->debit == $line->credit)) {
						$row->csv = $line;
						$line = null;
						break;
					}
				}
			}

			$lines[$id] = $row;
		}

		unset($j);

		foreach ($csv as $line) {
			if (null == $line) {
				continue;
			}

			$id = $line->date->format('Ymd') . '.' . $i++;
			$lines[$id] = (object) ['csv' => $line, 'journal' => null];
		}

		ksort($lines);


		foreach ($lines as &$line) {


			if (isset($line->csv)) {
				$sum += $line->csv->credit - $line->csv->debit;
				$line->csv->running_sum = $sum;













			}
		}

		return $lines;
	}

	public function getDepositJournal(int $year_id, array $checked = []): \Generator







|










<
<
<
<
<
<
<
<
<
<














|

















|




>


>
>

|

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







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278










279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
		$journal = iterator_to_array($journal);
		$i = 0;
		$sum = 0;

		foreach ($csv as $k => &$line) {
			try {
				$date = \DateTime::createFromFormat('!d/m/Y', $line->date);
				$line->amount = ($line->amount < 0 ? -1 : 1) * Utils::moneyToInteger($line->amount);

				if (!$date) {
					throw new UserException('Date invalide : ' . $line->date);
				}

				$line->date = $date;
			}
			catch (UserException $e) {
				throw new UserException(sprintf('Ligne %d : %s', $k, $e->getMessage()));
			}










		}
		unset($line);

		foreach ($journal as $j) {
			$id = $j->date->format('Ymd') . '.' . $i++;

			$row = (object) ['csv' => null, 'journal' => $j];

			if (isset($j->debit)) {
				foreach ($csv as &$line) {
					if (!isset($line->date)) {
						 continue;
					}
					if ($j->date->format('Ymd') == $line->date->format('Ymd')
						&& ($j->credit == abs($line->amount) || $j->debit == abs($line->amount))) {
						$row->csv = $line;
						$line = null;
						break;
					}
				}
			}

			$lines[$id] = $row;
		}

		unset($j);

		foreach ($csv as $line) {
			if (null == $line) {
				continue;
			}

			$id = $line->date->format('Ymd') . '.' . ($i++);
			$lines[$id] = (object) ['csv' => $line, 'journal' => null];
		}

		ksort($lines);
		$prev = null;

		foreach ($lines as &$line) {
			$line->add = false;

			if (isset($line->csv)) {
				$sum += $line->csv->amount;
				$line->csv->running_sum = $sum;

				if ($prev && ($prev->date->format('Ymd') != $line->csv->date->format('Ymd') || $prev->label != $line->csv->label)) {
					$prev = null;
				}
			}

			if (isset($line->csv) && isset($line->journal)) {
				$prev = null;
			}

			if (isset($line->csv) && !isset($line->journal) && !$prev) {
				$line->add = true;
				$prev = $line->csv;
			}
		}

		return $lines;
	}

	public function getDepositJournal(int $year_id, array $checked = []): \Generator

Modified src/templates/acc/accounts/reconcile_assist.tpl from [72a57f6b55] to [7d6e515a05].

28
29
30
31
32
33
34

35
36
37
38
39
40
41
				{button type="submit" name="upload" label="Envoyer le fichier" class="main" shape="upload"}
			</p>
		</fieldset>
	{elseif !$csv->ready()}
		{include file="common/_csv_match_columns.tpl"}
		<p class="submit">
			{csrf_field key=$csrf_key}

			{button type="submit" name="assign" label="Continuer" class="main" shape="right"}
		</p>
	{else}
		<fieldset>
			<legend>Relevé de compte</legend>
			<dl>
				<dt>







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
				{button type="submit" name="upload" label="Envoyer le fichier" class="main" shape="upload"}
			</p>
		</fieldset>
	{elseif !$csv->ready()}
		{include file="common/_csv_match_columns.tpl"}
		<p class="submit">
			{csrf_field key=$csrf_key}
			{button type="submit" name="cancel" value="1" label="Annuler" shape="left"}
			{button type="submit" name="assign" label="Continuer" class="main" shape="right"}
		</p>
	{else}
		<fieldset>
			<legend>Relevé de compte</legend>
			<dl>
				<dt>
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97


98
99
100
101
102
103
104
105
106
107

108

109
110




111
112
113







114
115
116
117
118
119
120
121
122
123
124
125
126

127

128
129
130
131
132
133
134
135
136
		Les écritures apparaissent ici dans le sens du relevé de banque, à l'inverse des journaux comptables.
	</p>

	<form method="post" action="{$self_url}">
		<table class="list">
			<thead>
				<tr>
					<th colspan="7">Journal du compte (compta)</th>
					<td class="separator">Correspondance</td>
					<th colspan="5" class="separator">Extrait de compte (banque)</th>
				</tr>
				<tr>
					<td class="check"><input type="checkbox" title="Tout cocher / décocher" id="f_all" /><label for="f_all"></label></td>
					<td></td>
					<td>Date</td>
					<td class="money">Débit</td>
					<td class="money">Crédit</td>
					<td class="money">Solde cumulé</td>
					<th>Libellé</th>
					<td></td>
					<td class="separator">Date</td>
					<th>Libellé</th>
					<td class="money">Débit</td>
					<td class="money">Crédit</td>
					<td class="money">Solde cumulé</td>

				</tr>
			</thead>
			<tbody>
				{foreach from=$lines item="line"}
				{if isset($line->journal->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>
					{if isset($line->journal)}
						<td class="check">
							{input type="checkbox" name="reconcile[%d]"|args:$line.journal.id_line value="1" default=$line.journal.reconciled}
						</td>
						<td class="num"><a href="{$admin_url}acc/transactions/details.php?id={$line.journal.id}">#{$line.journal.id}</a></td>
						<td>{$line.journal.date|date_short}</td>

						<td class="money">{$line.journal.credit|raw|html_money}</td>

						<td class="money">{$line.journal.debit|raw|html_money}</td> {* Not a bug! Credit/debit is reversed here to reflect the bank statement *}
						<td class="money">{if $line.journal.running_sum > 0}-{/if}{$line.journal.running_sum|abs|raw|html_money:false}</td>




						<th>{$line.journal.label}</th>
					{else}
						<td colspan="7"></td>







					{/if}
						<td class="separator">
						{if $line->journal && $line->csv}
							==
						{else}
							<b class="icn">⚠</b>
						{/if}
						</td>
					{if isset($line->csv)}
						<td class="separator">{$line.csv.date|date_short}</td>
						<th>{$line.csv.label}</th>
						<td class="money">{$line.csv.debit|raw|html_money}</td>
						<td class="money">{$line.csv.credit|raw|html_money}</td>

						<td class="money">{$line.csv.running_sum|raw|html_money}</td>

					{else}
						<td colspan="5" class="separator"></td>
					{/if}
				</tr>
				{/if}
			{/foreach}
			</tbody>
		</table>
		<p class="submit">







|
|
|





|
<

|
<
|
|
|
<

>



|


|
|
|
>
>
|









>
|
>
|
|
>
>
>
>
|

|
>
>
>
>
>
>
>









<
|
|
|
>

>

|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82

83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
		Les écritures apparaissent ici dans le sens du relevé de banque, à l'inverse des journaux comptables.
	</p>

	<form method="post" action="{$self_url}">
		<table class="list">
			<thead>
				<tr>
					<th colspan="6">Journal du compte (compta)</th>
					<td class="separator"></td>
					<th colspan="4" class="separator">Extrait de compte (banque)</th>
				</tr>
				<tr>
					<td class="check"><input type="checkbox" title="Tout cocher / décocher" id="f_all" /><label for="f_all"></label></td>
					<td></td>
					<td>Date</td>
					<td class="money">Mouvement</td>

					<td class="money">Solde cumulé</td>
					<th style="text-align: right">Libellé</th>

					<td class="separator"></td>
					<th class="separator">Libellé</th>
					<td class="money">Mouvement</td>

					<td class="money">Solde cumulé</td>
					<td>Date</td>
				</tr>
			</thead>
			<tbody>
				{foreach from=$lines key="line_id" item="line"}
				{if isset($line->journal->sum)}
				<tr>
					<td colspan="4"></td>
					<td class="money">{if $line.journal.sum > 0}-{/if}{$line.journal.sum|abs|raw|html_money:false}</td>
					<th style="text-align: right">Solde au {$line.journal.date|date_fr:'d/m/Y'}</th>
					<td class="separator"></td>
					<td class="separator"></td>
					<td colspan="3"></td>
				</tr>
				{else}
				<tr>
					{if isset($line->journal)}
						<td class="check">
							{input type="checkbox" name="reconcile[%d]"|args:$line.journal.id_line value="1" default=$line.journal.reconciled}
						</td>
						<td class="num"><a href="{$admin_url}acc/transactions/details.php?id={$line.journal.id}">#{$line.journal.id}</a></td>
						<td>{$line.journal.date|date_short}</td>
						<td class="money">{if $line.journal.running_sum > 0}-{/if}{$line.journal.running_sum|abs|raw|html_money:false}</td>
						<td class="money">
							{if $line.journal.credit}
								{* Not a bug! Credit/debit is reversed here to reflect the bank statement *}
								-{$line.journal.credit|raw|html_money}
							{else}
								{$line.journal.debit|raw|html_money}
							{/if}
						</td>
						<th style="text-align: right">{$line.journal.label}</th>
					{else}
						<td colspan="5"></td>
						<td style="text-align: right">
							{if $line.add}
							{* FIXME later add ability to pre-fill multi-line transactions in new.php
								{linkbutton label="Créer cette écriture" target="_blank" href="%s&create=%s"|args:$self_url,$line_id shape="plus"}
							*}
							{/if}
						</td>
					{/if}
						<td class="separator">
						{if $line->journal && $line->csv}
							==
						{else}
							<b class="icn">⚠</b>
						{/if}
						</td>
					{if isset($line->csv)}

						<th class="separator">{$line.csv.label}</th>
						<td class="money">
							{$line.csv.amount|raw|html_money}
						</td>
						<td class="money">{$line.csv.running_sum|raw|html_money}</td>
						<td>{$line.csv.date|date_short}</td>
					{else}
						<td colspan="4" class="separator"></td>
					{/if}
				</tr>
				{/if}
			{/foreach}
			</tbody>
		</table>
		<p class="submit">

Modified src/templates/acc/years/import.tpl from [a0409af25f] to [04e72548a2].

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
	</ul>
</nav>

{form_errors}

<form method="post" action="{$self_url}" enctype="multipart/form-data">

	{if $csv_file}

		{include file="common/_csv_match_columns.tpl"}







	{else}

	<fieldset>
		<legend>Import d'écritures</legend>
		<dl>
			<dt><label for="f_type_garradin">Format de fichier</label></dt>
			{input type="radio" name="type" value="garradin" label="Journal général au format CSV Garradin" default="garradin"}
			{input type="radio" name="type" value="csv" label="Journal au format CSV libre"}
			{include file="common/_csv_help.tpl"}
			{input type="file" name="file" label="Fichier CSV" accept=".csv,text/csv" required=1}
			<dd class="help block">
				- Les lignes comportant un numéro d'écriture mettront à jour les écritures existantes correspondant à ces numéros (sauf si celles-ci ont été validées), alors que les lignes sans numéro créeront de nouvelles écritures.<br />
				- Si le fichier comporte des écritures dont la date est en dehors de l'exercice courant, elles seront ignorées.
			</dd>
		</dl>
	</fieldset>

	{/if}

	<p class="submit">
		{csrf_field key="acc_years_import_%d"|args:$year.id}
		{if $csv_file}
			{button type="submit" name="cancel" label="Annuler" shape="left"}
		{/if}
		{button type="submit" name="import" label="Importer" shape="upload" class="main"}
	</p>



</form>

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







|



>
>
>
>
>
>
|
















<
<

|
<
<
<
|


>




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
	</ul>
</nav>

{form_errors}

<form method="post" action="{$self_url}" enctype="multipart/form-data">

{if $csv->loaded()}

		{include file="common/_csv_match_columns.tpl"}

		<p class="submit">
			{csrf_field key=$csrf_key}
			{button type="submit" name="cancel" value="1" label="Annuler" shape="left"}
			{button type="submit" name="assign" label="Continuer" class="main" shape="right"}
		</p>

{else}

	<fieldset>
		<legend>Import d'écritures</legend>
		<dl>
			<dt><label for="f_type_garradin">Format de fichier</label></dt>
			{input type="radio" name="type" value="garradin" label="Journal général au format CSV Garradin" default="garradin"}
			{input type="radio" name="type" value="csv" label="Journal au format CSV libre"}
			{include file="common/_csv_help.tpl"}
			{input type="file" name="file" label="Fichier CSV" accept=".csv,text/csv" required=1}
			<dd class="help block">
				- Les lignes comportant un numéro d'écriture mettront à jour les écritures existantes correspondant à ces numéros (sauf si celles-ci ont été validées), alors que les lignes sans numéro créeront de nouvelles écritures.<br />
				- Si le fichier comporte des écritures dont la date est en dehors de l'exercice courant, elles seront ignorées.
			</dd>
		</dl>
	</fieldset>



	<p class="submit">
		{csrf_field key=$csrf_key}



		{button type="submit" name="load" label="Importer" shape="upload" class="main"}
	</p>

{/if}

</form>

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

Modified src/www/admin/acc/accounts/reconcile_assist.php from [d2f7c5c971] to [a96b3c063b].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
	'p_reference'    => 'Référence paiement',
	'amount'         => 'Montant',
]);

$csv->setMandatoryColumns(['label', 'date', 'amount']);

$form->runIf('cancel', function () use ($csv) {
	$csv->cancel();
}, $csrf_key, Utils::getSelfURL());

$form->runIf(f('upload') && isset($_FILES['file']['name']), function () use ($csv) {
	$csv->load($_FILES['file']);
}, $csrf_key, Utils::getSelfURL());

$form->runIf('assign', function () use ($csv) {







|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
	'p_reference'    => 'Référence paiement',
	'amount'         => 'Montant',
]);

$csv->setMandatoryColumns(['label', 'date', 'amount']);

$form->runIf('cancel', function () use ($csv) {
	$csv->clear();
}, $csrf_key, Utils::getSelfURL());

$form->runIf(f('upload') && isset($_FILES['file']['name']), function () use ($csv) {
	$csv->load($_FILES['file']);
}, $csrf_key, Utils::getSelfURL());

$form->runIf('assign', function () use ($csv) {
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
if ($start && $end) {
	$journal = $account->getReconcileJournal(CURRENT_YEAR_ID, $start, $end);
}

// Enregistrement des cases cochées
$form->runIf('save', function () use ($journal, $csv) {
	Transactions::saveReconciled($journal, f('reconcile'));
	$csv->cancel();
}, $csrf_key, Utils::getSelfURL());

$lines = null;

if ($journal && $csv->ready()) {
	try {
		$lines = $account->mergeReconcileJournalAndCSV($journal, $csv);







|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
if ($start && $end) {
	$journal = $account->getReconcileJournal(CURRENT_YEAR_ID, $start, $end);
}

// Enregistrement des cases cochées
$form->runIf('save', function () use ($journal, $csv) {
	Transactions::saveReconciled($journal, f('reconcile'));
	$csv->clear();
}, $csrf_key, Utils::getSelfURL());

$lines = null;

if ($journal && $csv->ready()) {
	try {
		$lines = $account->mergeReconcileJournalAndCSV($journal, $csv);

Modified src/www/admin/acc/years/import.php from [8c922cab95] to [3baf406550].

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
81
82
83
84
85
86
87
88

89
90
91

92

93
94
95
96
97
98
99
100
101
	exit;
}

if ($year->closed) {
	throw new UserException('Impossible de modifier un exercice clôturé.');
}

if (f('cancel')) {
	$session->set('acc_import_csv', null);
}

$csv_file = $session->get('acc_import_csv');

if (f('import') && $csv_file && $form->check('acc_years_import_' . $year->id(), ['translate' => 'array|required']))
{

	try {
		Transactions::importArray($year, $csv_file, f('translate'), (int) f('skip_first_line'), $user->id);
		$session->set('acc_import_csv', null);
		Utils::redirect(ADMIN_URL . 'acc/years/');
	}
	catch (UserException $e) {
		$form->addError($e->getMessage());
	}
}
elseif (f('import') && $form->check('acc_years_import_' . $year->id(), ['file' => 'file|required']))
{
	try {

		if (f('type') === 'csv') {
			$csv = CSV::readAsArray($_FILES['file']['tmp_name']);
			$session->set('acc_import_csv', $csv);
			Utils::redirect(Utils::getSelfURI());
		}
		else {
			Transactions::importCSV($year, $_FILES['file'], $user->id);
		}

		Utils::redirect(ADMIN_URL . 'acc/years/');
	}
	catch (UserException $e)
	{
		$form->addError($e->getMessage());
	}
}

$csv_first_line = null;
$csv_selected = [];

if ($csv_file) {
	$csv_first_line = reset($csv_file);
	$csv_selected = [];

	foreach ($csv_first_line as $index => $label) {
		$label = trim($label);

		if (isset($_POST['translate'][$index])) {
			$csv_selected[$index] = $_POST['translate'][$index];
		}
		elseif (false !== ($pos = array_search($label, Transactions::POSSIBLE_CSV_COLUMNS, true))) {
			$csv_selected[$index] = $pos;

		}
		else {
			$csv_selected[$index] = null;

		}

	}
}

$tpl->assign('columns', implode(', ', array_intersect_key(Transactions::POSSIBLE_CSV_COLUMNS, array_flip(Transactions::MANDATORY_CSV_COLUMNS))));
$tpl->assign('other_columns', implode(', ', array_diff_key(Transactions::POSSIBLE_CSV_COLUMNS, array_flip(Transactions::MANDATORY_CSV_COLUMNS))));
$tpl->assign('possible_columns', Transactions::POSSIBLE_CSV_COLUMNS);
$tpl->assign(compact('csv_file', 'year', 'csv_first_line', 'csv_selected'));

$tpl->display('acc/years/import.tpl');







<
|
<
|
<
|
<
|
>
|
<
<
|
|
<
<
|
<
|
|
<
>
|
<
|
<
|
<
|
<
|
|
<
<
|
<
<
<
|
<
<
|
<
<
<
|
<
<
|
<
<
|
|
|
>
|
|
<
>
|
>
|
<
<
<
<
<
|


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
	exit;
}

if ($year->closed) {
	throw new UserException('Impossible de modifier un exercice clôturé.');
}


$csv = new CSV_Custom($session, 'acc_import_year');

$csv->setColumns(Transactions::POSSIBLE_CSV_COLUMNS);

$csv->setMandatoryColumns(Transactions::MANDATORY_CSV_COLUMNS);


if (f('cancel')) {
	$csv->clear();


	Utils::redirect(Utils::getSelfURL());
}




$csrf_key = 'acc_years_import_' . $year->id();


$form->runIf(f('assign') && $csv->loaded(), function () use ($csv, $year, $user) {
	$csv->skip(f('skip_first_line'));

	$csv->setTranslationTable(f('translation_table'));



	Transactions::importCustom($year, $csv, $user->id);

	$csv->clear();
}, $csrf_key, ADMIN_URL . 'acc/years/');






$form->runIf('load', function () use ($csv, $year, $user) {


	if (f('type') == 'garradin') {



		Transactions::importCSV($year, $_FILES['file'], $user->id);


		Utils::redirect(ADMIN_URL . 'acc/years/');


	}
	elseif (isset($_FILES['file']['tmp_name'])) {
		$csv->load($_FILES['file']);
		Utils::redirect(Utils::getSelfURI());
	}
	else {

		throw new UserException('Fichier invalide');
	}
}, $csrf_key, Utils::getSelfURI());






$tpl->assign(compact('csv', 'year', 'csrf_key'));

$tpl->display('acc/years/import.tpl');