Overview
Comment:Implement: chart edition, restrict changes of archived charts
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA1: 77f341a31476becbebadb5601acb7c4c58180561
User & Date: bohwaz on 2020-10-14 19:40:59
Other Links: branch diff | manifest | tags
Context
2020-10-14
21:06
Implement: chart removal check-in: d6dd4a7348 user: bohwaz tags: dev
19:40
Implement: chart edition, restrict changes of archived charts check-in: 77f341a314 user: bohwaz tags: dev
19:13
Implement: add / copy chart check-in: e7d84b2f9e user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Entities/Accounting/Account.php from [92accb5b2a] to [cf998fe9a0].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
<?php

namespace Garradin\Entities\Accounting;

use DateTimeInterface;
use Garradin\Entity;
use Garradin\DB;
use Garradin\Utils;
use Garradin\UserException;
use Garradin\ValidationException;


class Account extends Entity
{
	const TABLE = 'acc_accounts';

	// Actif
	const ASSET = 1;










>







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

namespace Garradin\Entities\Accounting;

use DateTimeInterface;
use Garradin\Entity;
use Garradin\DB;
use Garradin\Utils;
use Garradin\UserException;
use Garradin\ValidationException;
use Garradin\Accounting\Charts;

class Account extends Entity
{
	const TABLE = 'acc_accounts';

	// Actif
	const ASSET = 1;
219
220
221
222
223
224
225
226





	{
		return !DB::getInstance()->firstColumn(sprintf('SELECT 1 FROM %s l
			INNER JOIN %s t ON t.id = l.id_transaction
			INNER JOIN %s y ON y.id = t.id_year
			WHERE l.id_account = ? AND y.closed = 1
			LIMIT 1;', Line::TABLE, Transaction::TABLE, Year::TABLE), $this->id());
	}
}












|
>
>
>
>
>
220
221
222
223
224
225
226
227
228
229
230
231
232
	{
		return !DB::getInstance()->firstColumn(sprintf('SELECT 1 FROM %s l
			INNER JOIN %s t ON t.id = l.id_transaction
			INNER JOIN %s y ON y.id = t.id_year
			WHERE l.id_account = ? AND y.closed = 1
			LIMIT 1;', Line::TABLE, Transaction::TABLE, Year::TABLE), $this->id());
	}

	public function chart(): Chart
	{
		return Charts::get($this->id_chart);
	}
}

Modified src/include/lib/Garradin/Entities/Accounting/Chart.php from [0953241c8f] to [bbc0da88a7].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
		'code'     => '?string',
		'archived' => 'int',
	];

	protected $_form_rules = [
		'label'    => 'required|string|max:200',
		'country'  => 'required|string|size:2',
		'code'     => 'string',
	];

	public function selfCheck(): void
	{
		parent::selfCheck();
		$this->assert(Utils::getCountryName($this->country), 'Le code pays doit être un code ISO valide');
		$this->assert($this->archived === 0 || $this->archived === 1);







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
		'code'     => '?string',
		'archived' => 'int',
	];

	protected $_form_rules = [
		'label'    => 'required|string|max:200',
		'country'  => 'required|string|size:2',
		'archived' => 'numeric|min:0|max:1'
	];

	public function selfCheck(): void
	{
		parent::selfCheck();
		$this->assert(Utils::getCountryName($this->country), 'Le code pays doit être un code ISO valide');
		$this->assert($this->archived === 0 || $this->archived === 1);

Modified src/include/lib/Garradin/Template.php from [338bc036fa] to [8f3272630e].

217
218
219
220
221
222
223


224
225
226
227
228
229
230

		if ($type == 'radio' || $type == 'checkbox') {
			$attributes['id'] .= '_' . $value;

			if ($current_value == $value) {
				$attributes['checked'] = 'checked';
			}


		}
		elseif ($type == 'file') {
			$help = sprintf('Taille maximale : %s', Utils::format_bytes(Utils::getMaxUploadSize()));
		}
		elseif ($type == 'date') {
			$type = 'text';
			$attributes['placeholder'] = 'JJ/MM/AAAA';







>
>







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

		if ($type == 'radio' || $type == 'checkbox') {
			$attributes['id'] .= '_' . $value;

			if ($current_value == $value) {
				$attributes['checked'] = 'checked';
			}

			$attributes['value'] = $value;
		}
		elseif ($type == 'file') {
			$help = sprintf('Taille maximale : %s', Utils::format_bytes(Utils::getMaxUploadSize()));
		}
		elseif ($type == 'date') {
			$type = 'text';
			$attributes['placeholder'] = 'JJ/MM/AAAA';

Modified src/templates/acc/charts/accounts/all.tpl from [5a754ce342] to [36a589be55].

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
					{icon shape="star"} <?=Entities\Accounting\Account::TYPES_NAMES[$account->type]?>
				{/if}
			</td>
			<td>
				{if $account.user}<em>Ajouté</em>{/if}
			</td>
			<td class="actions">
				{if $session->canAccess('compta', Membres::DROIT_ADMIN)}
					{linkbutton shape="edit" label="Modifier" href="acc/charts/accounts/edit.php?id=%d"|args:$account.id}
					{linkbutton shape="delete" label="Supprimer" href="acc/charts/accounts/delete.php?id=%d"|args:$account.id}
				{/if}
			</td>
		</tr>
	{/foreach}
	</tbody>
</table>


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







|











17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
					{icon shape="star"} <?=Entities\Accounting\Account::TYPES_NAMES[$account->type]?>
				{/if}
			</td>
			<td>
				{if $account.user}<em>Ajouté</em>{/if}
			</td>
			<td class="actions">
				{if $session->canAccess('compta', Membres::DROIT_ADMIN) && !$chart.archived}
					{linkbutton shape="edit" label="Modifier" href="acc/charts/accounts/edit.php?id=%d"|args:$account.id}
					{linkbutton shape="delete" label="Supprimer" href="acc/charts/accounts/delete.php?id=%d"|args:$account.id}
				{/if}
			</td>
		</tr>
	{/foreach}
	</tbody>
</table>


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

Modified src/templates/acc/charts/accounts/index.tpl from [3bde12849f] to [397d4ff587].

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
{include file="admin/_head.tpl" title="Comptes favoris" current="acc/charts"}

{include file="acc/charts/accounts/_nav.tpl" current="favorites"}

<table class="list">
{foreach from=$accounts_grouped item="group"}
	<tbody>
		<tr>
			<td colspan="3"><h2 class="ruler">{$group.label}</h2></td>
			<td class="actions">

				{linkbutton label="Ajouter un compte" shape="plus" href="acc/charts/accounts/new.php?id=%d&type=%d"|args:$chart.id,$group.type}

			</td>
		</tr>

	{foreach from=$group.accounts item="account"}
		<tr>
			<td class="num">{$account.code}</td>
			<th>{$account.label}</th>
			<td class="desc">{$account.description}</td>
			<td class="actions">
				{if $session->canAccess('compta', Membres::DROIT_ADMIN)}
					{linkbutton shape="edit" label="Modifier" href="acc/charts/accounts/edit.php?id=%d"|args:$account.id}
					{linkbutton shape="delete" label="Supprimer" href="acc/charts/accounts/delete.php?id=%d"|args:$account.id}
				{/if}
			</td>
		</tr>
	{/foreach}
	</tbody>
{/foreach}
</table>

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










>
|
>









|











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
{include file="admin/_head.tpl" title="Comptes favoris" current="acc/charts"}

{include file="acc/charts/accounts/_nav.tpl" current="favorites"}

<table class="list">
{foreach from=$accounts_grouped item="group"}
	<tbody>
		<tr>
			<td colspan="3"><h2 class="ruler">{$group.label}</h2></td>
			<td class="actions">
				{if !$chart.archived}
					{linkbutton label="Ajouter un compte" shape="plus" href="acc/charts/accounts/new.php?id=%d&type=%d"|args:$chart.id,$group.type}
				{/if}
			</td>
		</tr>

	{foreach from=$group.accounts item="account"}
		<tr>
			<td class="num">{$account.code}</td>
			<th>{$account.label}</th>
			<td class="desc">{$account.description}</td>
			<td class="actions">
				{if $session->canAccess('compta', Membres::DROIT_ADMIN) && !$chart.archived}
					{linkbutton shape="edit" label="Modifier" href="acc/charts/accounts/edit.php?id=%d"|args:$account.id}
					{linkbutton shape="delete" label="Supprimer" href="acc/charts/accounts/delete.php?id=%d"|args:$account.id}
				{/if}
			</td>
		</tr>
	{/foreach}
	</tbody>
{/foreach}
</table>

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

Added src/templates/acc/charts/edit.tpl version [689374e0cf].











































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{include file="admin/_head.tpl" title="Modifier un plan comptable" current="acc/charts"}

{form_errors}

<form method="post" action="{$self_url}">
	<fieldset>
		<legend>Modifier un plan comptable</legend>
		<dl>
			{input type="text" name="label" label="Libellé" required=1 source=$chart}
			{input type="select" name="country" label="Pays" required=1 options=$country_list source=$chart}
			<dt><label for="f_archived_1">Archivage</label></dt>
			{input type="checkbox" name="archived" value="1" source=$chart label="Plan comptable archivé" help="Ce plan comptable ne pourra plus être modifié"}
		</dl>
		<p class="submit">
			{csrf_field key="acc_charts_edit_%d"|args:$chart.id}
			<input type="submit" name="save" value="Enregistrer &rarr;" />
		</p>
	</fieldset>
</form>

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

Modified src/templates/acc/charts/index.tpl from [8e19ab31c8] to [4a0d3f664c].

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
{/if}

{if count($list)}
	<table class="list">
		<thead>
			<td>Pays</td>
			<th>Libellé</th>


			<td></td>
		</thead>
		<tbody>
			{foreach from=$list item="item"}
				<tr>
					<td>{$item.country|get_country_name}</td>
					<th><a href="{$admin_url}acc/charts/accounts/?id={$item.id}">{$item.label}</a> <em>{if $item.code}(officiel){else}(copie){/if}</em></th>


					<td>
						{linkbutton shape="star" label="Comptes favoris" href="acc/charts/accounts/?id=%d"|args:$item.id}
						{linkbutton shape="menu" label="Tous les comptes" href="acc/charts/accounts/all.php?id=%d"|args:$item.id}
						{if $session->canAccess('compta', Membres::DROIT_ADMIN)}
							{linkbutton shape="edit" label="Modifier" href="acc/charts/edit.php?id=%d"|args:$item.id}
							{linkbutton shape="export" label="Exporter en CSV" href="acc/charts/export.php?id=%d"|args:$item.id}
							{if empty($item.code)}
								{linkbutton shape="delete" label="Supprimer" href="acc/charts/delete.php?id=%d"|args:$item.id}
							{/if}
						{/if}
					</td>
				</tr>
			{/foreach}
		</tbody>







>
>




|

|
>
>






|







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
{/if}

{if count($list)}
	<table class="list">
		<thead>
			<td>Pays</td>
			<th>Libellé</th>
			<td>Type</td>
			<td>Archivé</td>
			<td></td>
		</thead>
		<tbody>
			{foreach from=$list item="item"}
				<tr{if $item.archived} class="disabled"{/if}>
					<td>{$item.country|get_country_name}</td>
					<th><a href="{$admin_url}acc/charts/accounts/?id={$item.id}">{$item.label}</a></th>
					<td>{if $item.code}Officiel{else}Copie{/if}</td>
					<td>{if $item.archived}<em>Archivé</em>{/if}</td>
					<td>
						{linkbutton shape="star" label="Comptes favoris" href="acc/charts/accounts/?id=%d"|args:$item.id}
						{linkbutton shape="menu" label="Tous les comptes" href="acc/charts/accounts/all.php?id=%d"|args:$item.id}
						{if $session->canAccess('compta', Membres::DROIT_ADMIN)}
							{linkbutton shape="edit" label="Modifier" href="acc/charts/edit.php?id=%d"|args:$item.id}
							{linkbutton shape="export" label="Exporter en CSV" href="acc/charts/export.php?id=%d"|args:$item.id}
							{if !$item.code && !$item.archived}
								{linkbutton shape="delete" label="Supprimer" href="acc/charts/delete.php?id=%d"|args:$item.id}
							{/if}
						{/if}
					</td>
				</tr>
			{/foreach}
		</tbody>

Modified src/www/admin/acc/charts/accounts/delete.php from [27e2989767] to [4ee1d4bb72].

8
9
10
11
12
13
14






15
16
17
18
19
20
21
$session->requireAccess('compta', Membres::DROIT_ADMIN);

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

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







if (!$account->canDelete()) {
	throw new UserException("Ce compte ne peut être supprimé car des écritures y sont liées (peut-être sur l'exercice courant ou sur un exercice clôt).\nSi vous souhaitez faire du ménage dans la liste des comptes il est recommandé de créer un nouveau comptable.");
}

if (f('delete') && $form->check('acc_accounts_delete_' . $account->id()))
{







>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$session->requireAccess('compta', Membres::DROIT_ADMIN);

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

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

$chart = $account->chart();

if ($chart->archived) {
	throw new UserException("Il n'est pas possible de modifier un compte d'un plan comptable archivé.");
}

if (!$account->canDelete()) {
	throw new UserException("Ce compte ne peut être supprimé car des écritures y sont liées (peut-être sur l'exercice courant ou sur un exercice clôt).\nSi vous souhaitez faire du ménage dans la liste des comptes il est recommandé de créer un nouveau comptable.");
}

if (f('delete') && $form->check('acc_accounts_delete_' . $account->id()))
{

Modified src/www/admin/acc/charts/accounts/edit.php from [07b29516a9] to [22d9b33346].

8
9
10
11
12
13
14






15
16
17
18
19
20
21
$session->requireAccess('compta', Membres::DROIT_ADMIN);

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

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







$can_edit = $account->canEdit();

if (f('edit') && $form->check('acc_accounts_edit_' . $account->id()))
{
	try
	{







>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$session->requireAccess('compta', Membres::DROIT_ADMIN);

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

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

$chart = $account->chart();

if ($chart->archived) {
	throw new UserException("Il n'est pas possible de modifier un compte d'un plan comptable archivé.");
}

$can_edit = $account->canEdit();

if (f('edit') && $form->check('acc_accounts_edit_' . $account->id()))
{
	try
	{

Modified src/www/admin/acc/charts/accounts/new.php from [a766140b57] to [d3b601d02a].

10
11
12
13
14
15
16




17
18
19
20
21
22
23
$session->requireAccess('compta', Membres::DROIT_ADMIN);

$chart = Charts::get((int)qg('id'));

if (!$chart) {
	throw new UserException('Ce plan comptable n\'existe pas');
}





$account = new Account;
$account->position = Account::ASSET_OR_LIABILITY;

$types = $account::TYPES_NAMES;
$types[0] = '-- Pas un compte favori';








>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$session->requireAccess('compta', Membres::DROIT_ADMIN);

$chart = Charts::get((int)qg('id'));

if (!$chart) {
	throw new UserException('Ce plan comptable n\'existe pas');
}

if ($chart->archived) {
	throw new UserException("Il n'est pas possible de modifier un plan comptable archivé.");
}

$account = new Account;
$account->position = Account::ASSET_OR_LIABILITY;

$types = $account::TYPES_NAMES;
$types[0] = '-- Pas un compte favori';

Added src/www/admin/acc/charts/edit.php version [e0ba778302].





































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<?php
namespace Garradin;

use Garradin\Accounting\Charts;

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

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

$chart = Charts::get((int) qg('id'));

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

if (f('save') && $form->check('acc_charts_edit_' . $chart->id()))
{
	try
	{
		$chart->importForm();
		$chart->save();

		Utils::redirect(sprintf('%sacc/charts/', ADMIN_URL));
	}
	catch (UserException $e)
	{
		$form->addError($e->getMessage());
	}
}

$tpl->assign(compact('chart'));
$tpl->assign('country_list', Utils::getCountryList());

$tpl->display('acc/charts/edit.tpl');

Modified src/www/admin/static/admin.css from [b41fc487e9] to [5f32f7e896].

702
703
704
705
706
707
708




709
710
711
712
713
714
715
    border: 1px solid rgba(var(--gSecondColor), 0.5);
    transition: background .2s
}

table.list tr:nth-child(even), table.multi tbody:nth-child(even) {
    background: rgba(var(--gSecondColor), 0.2);
}





table.multi tr {
    background: inherit !important;
}

table.list tr.checked {
    color: #633;







>
>
>
>







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
    border: 1px solid rgba(var(--gSecondColor), 0.5);
    transition: background .2s
}

table.list tr:nth-child(even), table.multi tbody:nth-child(even) {
    background: rgba(var(--gSecondColor), 0.2);
}

table.list tr.disabled {
    color: #666;
}

table.multi tr {
    background: inherit !important;
}

table.list tr.checked {
    color: #633;