Overview
Comment: | Allow to move transactions past the closing date to another year |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | stable |
Files: | files | file ages | folders |
SHA1: |
addcc82d4afa23901ae7df7596548c17 |
User & Date: | bohwaz on 2020-12-12 23:24:02 |
Other Links: | manifest | tags |
Context
2020-12-13
| ||
14:18 | Put 890 and 891 in the closing balance or the balance won't be balanced check-in: b744edc852 user: bohwaz tags: trunk, stable, 1.0.0-rc14 | |
2020-12-12
| ||
23:24 | Allow to move transactions past the closing date to another year check-in: addcc82d4a user: bohwaz tags: trunk, stable | |
13:36 | Display chart name in years list check-in: cabdc28bd5 user: bohwaz tags: trunk, stable | |
Changes
Modified src/include/lib/Garradin/Accounting/Years.php from [c98819983d] to [d5bc306cae].
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 | static public function listOpen() { $db = EntityManager::getInstance(Year::class)->DB(); return $db->get('SELECT *, (SELECT COUNT(*) FROM acc_transactions WHERE id_year = acc_years.id) AS nb_transactions FROM acc_years WHERE closed = 0 ORDER BY end_date;'); } static public function listAssoc() { return DB::getInstance()->getAssoc('SELECT id, label FROM acc_years ORDER BY end_date;'); } static public function listClosed() | > > > > > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | static public function listOpen() { $db = EntityManager::getInstance(Year::class)->DB(); return $db->get('SELECT *, (SELECT COUNT(*) FROM acc_transactions WHERE id_year = acc_years.id) AS nb_transactions FROM acc_years WHERE closed = 0 ORDER BY end_date;'); } static public function listOpenAssocExcept(int $id) { $db = EntityManager::getInstance(Year::class)->DB(); return $db->getAssoc('SELECT id, label FROM acc_years WHERE closed = 0 AND id != ? ORDER BY end_date;', $id); } static public function listAssoc() { return DB::getInstance()->getAssoc('SELECT id, label FROM acc_years ORDER BY end_date;'); } static public function listClosed() |
︙ | ︙ |
Modified src/include/lib/Garradin/Entities/Accounting/Year.php from [efb670bde0] to [3f994637f5].
︙ | ︙ | |||
45 46 47 48 49 50 51 | $db = DB::getInstance(); $this->assert($this->id_chart !== null); if ($this->exists()) { $this->assert( !$db->test(Transaction::TABLE, 'id_year = ? AND date < ?', $this->id(), $this->start_date->format('Y-m-d')), | | | > > > > > > > > > > > > > > > > > > | 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 | $db = DB::getInstance(); $this->assert($this->id_chart !== null); if ($this->exists()) { $this->assert( !$db->test(Transaction::TABLE, 'id_year = ? AND date < ?', $this->id(), $this->start_date->format('Y-m-d')), 'Des écritures de cet exercice ont une date antérieure à la date de début de l\'exercice.' ); $this->assert( !$db->test(Transaction::TABLE, 'id_year = ? AND date > ?', $this->id(), $this->end_date->format('Y-m-d')), 'Des écritures de cet exercice ont une date postérieure à la date de fin de l\'exercice.' ); } } public function close(int $user_id): void { if ($this->closed) { throw new \LogicException('Cet exercice est déjà clôturé'); } $this->set('closed', 1); $this->save(); } /** * Splits an accounting year between the current year and another one, at a given date * Any transaction after the given date will be moved to the target year. */ public function split(\DateTime $date, Year $target): void { if ($this->closed) { throw new \LogicException('Cet exercice est déjà clôturé'); } if ($target->closed) { throw new \LogicException('L\'exercice cible est déjà clôturé'); } DB::getInstance()->preparedQuery('UPDATE acc_transactions SET id_year = ? WHERE id_year = ? AND date > ?;', $target->id(), $this->id(), $date->format('Y-m-d')); } public function delete(): bool { // Manual delete of transactions, as there is a voluntary safeguard in SQL: no cascade DB::getInstance()->preparedQuery('DELETE FROM acc_transactions WHERE id_year = ?;', $this->id()); // Clean up files |
︙ | ︙ |
Modified src/templates/acc/years/close.tpl from [a98ff863c3] to [5b77dd26f5].
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 | Il ne sera plus possible de modifier ou supprimer les écritures de l'exercice clôturé. </p> <dl> <dt>Début de l'exercice</dt> <dd>{$year.start_date|date_short}</dd> <dt>Fin de l'exercice</dt> <dd>{$year.end_date|date_short}</dd> </h3> </fieldset> <p class="help">Les soldes créditeurs ou débiteurs de chaque compte pourront être reportés automatiquement lors de l'ouverture de l'exercice suivant.</p> <p class="submit"> | > | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | Il ne sera plus possible de modifier ou supprimer les écritures de l'exercice clôturé. </p> <dl> <dt>Début de l'exercice</dt> <dd>{$year.start_date|date_short}</dd> <dt>Fin de l'exercice</dt> <dd>{$year.end_date|date_short}</dd> <dd class="help">Si la date de clôture ne convient pas, il est possible de <a href="edit.php?id={$year.id}">modifier l'exercice</a> préalablement à la clôture.</dd> </h3> </fieldset> <p class="help">Les soldes créditeurs ou débiteurs de chaque compte pourront être reportés automatiquement lors de l'ouverture de l'exercice suivant.</p> <p class="submit"> {csrf_field key=$csrf_key} {button type="submit" name="close" label="Clôturer" shape="lock" class="main"} </p> </form> {include file="admin/_foot.tpl"} |
Modified src/templates/acc/years/edit.tpl from [6825ad64b8] to [4ca0a535a8].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | {include file="admin/_head.tpl" title="Modifier un exercice" current="acc/years"} {form_errors} <form method="post" action="{$self_url}" data-focus="1"> <fieldset> <legend>Modifier un exercice</legend> <dl> {input type="text" label="Libellé" name="label" source=$year required=true} {input type="date" label="Début de l'exercice" name="start_date" source=$year required=true} {input type="date" label="Fin de l'exercice" name="end_date" source=$year required=true} </dl> </fieldset> <p class="submit"> {csrf_field key="acc_years_edit_%s"|args:$year.id} {button type="submit" name="edit" label="Enregistrer" shape="right" class="main"} </p> </form> {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 35 36 37 38 39 | {include file="admin/_head.tpl" title="Modifier un exercice" current="acc/years"} {form_errors} <form method="post" action="{$self_url}" data-focus="1"> <fieldset> <legend>Modifier un exercice</legend> <dl> {input type="text" label="Libellé" name="label" source=$year required=true} {input type="date" label="Début de l'exercice" name="start_date" source=$year required=true} {input type="date" label="Fin de l'exercice" name="end_date" source=$year required=true} {input type="checkbox" label="Déplacer les écritures postérieures dans un autre exercice" value=1 name="split"} </dl> <dl class="split_year"> <dd class="help">En cochant cette case, toute écriture située <em>après</em> la date de fin indiquée ci-dessus sera déplacée dans l'exercice sélectionné ci-dessous.</dd> {input type="select" name="split_year" options=$split_years label="Nouvel exercice à utiliser" help="Les écritures situées après la date de fin seront transférées dans cet exercice"} </dl> </fieldset> <p class="submit"> {csrf_field key="acc_years_edit_%s"|args:$year.id} {button type="submit" name="edit" label="Enregistrer" shape="right" class="main"} </p> </form> {literal} <script type="text/javascript"> let split = $('#f_split_1'); g.toggle('.split_year', split.checked); split.onchange = () => { g.toggle('.split_year', split.checked); }; </script> {/literal} {include file="admin/_foot.tpl"} |
Modified src/www/admin/acc/years/close.php from [c2cd93158e] to [e25c1f315a].
︙ | ︙ | |||
13 14 15 16 17 18 19 | throw new UserException('Exercice inconnu.'); } if ($year->closed) { throw new UserException('Impossible de modifier un exercice clôturé.'); } | < < < < | | < > | | | < | | < < < < < < | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | throw new UserException('Exercice inconnu.'); } if ($year->closed) { throw new UserException('Impossible de modifier un exercice clôturé.'); } $csrf_key = 'acc_years_close_' . $year->id(); $form->runIf('close', function () use ($year, $user, $session) { $year->close($user->id); $year->save(); $session->set('acc_year', null); }, $csrf_key, ADMIN_URL . 'acc/years/'); $tpl->assign(compact('year', 'csrf_key')); $tpl->display('acc/years/close.tpl'); |
Modified src/www/admin/acc/years/edit.php from [43b8da34f3] to [1f8f1a8a07].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php namespace Garradin; use Garradin\Accounting\Years; require_once __DIR__ . '/../_inc.php'; $session->requireAccess('compta', Membres::DROIT_ADMIN); $year = Years::get((int)qg('id')); if (!$year) { throw new UserException('Exercice inconnu.'); } if ($year->closed) { throw new UserException('Impossible de modifier un exercice clôturé.'); } | > | | > > > > > > > > > > > > > | > > > > > | | | | > > | < | | | > > > | > | 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 | <?php namespace Garradin; use Garradin\Accounting\Years; use Garradin\Entities\Accounting\Year; require_once __DIR__ . '/../_inc.php'; $session->requireAccess('compta', Membres::DROIT_ADMIN); $year = Years::get((int)qg('id')); if (!$year) { throw new UserException('Exercice inconnu.'); } if ($year->closed) { throw new UserException('Impossible de modifier un exercice clôturé.'); } $csrf_key = 'acc_years_edit_' . $year->id(); $form->runIf('edit', function () use ($year) { if (f('split')) { $date = \DateTime::createFromFormat('!d/m/Y', f('end_date')); if (!$date) { throw new UserException('Date de séparation invalide'); } $target = f('split_year'); if ($target) { $target = Years::get($target); } else { $target = new Year; $new_start = (clone $date)->modify('+1 day'); $target->label = sprintf('Exercice %d', $date->format('Y')); $target->start_date = $new_start; $target->end_date = (clone $new_start)->modify('+1 year'); $target->id_chart = $year->id_chart; $target->save(); } if (!$target) { throw new UserException('Exercice de séparation invalide'); } $year->split($date, $target); } $year->importForm(); $year->save(); }, $csrf_key, ADMIN_URL . 'acc/years/'); $tpl->assign(compact('year', 'csrf_key')); $tpl->assign('split_years', ['' => '-- Créer un nouvel exercice'] + Years::listOpenAssocExcept($year->id())); $tpl->display('acc/years/edit.tpl'); |