Overview
Comment: | Implement duplicate transaction button |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | stable |
Files: | files | file ages | folders |
SHA3-256: |
0cfe628c98e91df7c7fd1d83c73a95eb |
User & Date: | bohwaz on 2021-10-01 00:46:53 |
Other Links: | manifest | tags |
Context
2021-10-01
| ||
00:49 | Only shown "add payment" button when the service is linked to accounting check-in: 90c1d755e2 user: bohwaz tags: trunk, stable | |
00:46 | Implement duplicate transaction button check-in: 0cfe628c98 user: bohwaz tags: trunk, stable | |
2021-09-30
| ||
23:42 | Fix page reloads that were triggered when not needed, reverting page type to "page" instead of category check-in: 006cbd71fa user: bohwaz tags: trunk, stable | |
Changes
Modified src/include/lib/Garradin/Entities/Accounting/Transaction.php from [07be54e40e] to [32bd594806].
︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 'reference' => 'string|max:200', 'date' => 'required|date_format:d/m/Y', ]; protected $_lines; protected $_old_lines = []; /** * @var Transaction */ protected $_related; static public function getTypeFromAccountType(int $account_type) { | > > | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 'reference' => 'string|max:200', 'date' => 'required|date_format:d/m/Y', ]; protected $_lines; protected $_old_lines = []; protected $_accounts = []; /** * @var Transaction */ protected $_related; static public function getTypeFromAccountType(int $account_type) { |
︙ | ︙ | |||
113 114 115 116 117 118 119 | return self::TYPE_ADVANCED; } } /** * @param bool $restrict_year Set to TRUE to only return lines linked to the correct chart, or FALSE (deprecated/legacy) to return all lines even if they are linked to accounts in the wrong chart! */ | | | > > | | | | | | | | | > > > > > > | > > > > | > > | | > > > > > > > > > > > > > > > > > > > > | | 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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | return self::TYPE_ADVANCED; } } /** * @param bool $restrict_year Set to TRUE to only return lines linked to the correct chart, or FALSE (deprecated/legacy) to return all lines even if they are linked to accounts in the wrong chart! */ public function getLinesWithAccounts(bool $restrict_year = true): array { $db = EntityManager::getInstance(Line::class)->DB(); if (null === $this->_lines || $restrict_year === false) { $restrict = $restrict_year ? 'AND a.id_chart = y.id_chart' : ''; $sql = sprintf('SELECT l.*, a.label AS account_name, a.code AS account_code, b.label AS analytical_name FROM acc_transactions_lines l INNER JOIN acc_accounts a ON a.id = l.id_account %s INNER JOIN acc_transactions t ON t.id = l.id_transaction INNER JOIN acc_years y ON y.id = t.id_year LEFT JOIN acc_accounts b ON b.id = l.id_analytical WHERE l.id_transaction = %d ORDER BY l.id;', $restrict, $this->id()); return $db->get($sql); } else { // Merge data from accounts with lines $accounts = []; $lines_with_accounts = []; foreach ($this->getLines() as $line) { if (!array_key_exists($line->id_account, $this->_accounts)) { $accounts[] = $line->id_account; } if ($line->id_analytical && !array_key_exists($line->id_analytical, $this->_accounts)) { $accounts[] = $line->id_analytical; } } if (count($accounts)) { $sql = sprintf('SELECT id, label, code FROM acc_accounts WHERE %s;', $db->where('id', 'IN', $accounts)); $this->_accounts += $db->getGrouped($sql); } foreach ($this->getLines() as $line) { $account = [ 'account_code' => $this->_accounts[$line->id_account]->code, 'account_name' => $this->_accounts[$line->id_account]->label, 'analytical_name' => $line->id_analytical ? $this->_accounts[$line->id_analytical]->label : null, ]; $lines_with_accounts[] = (object) ($line->asArray() + $account); } return $lines_with_accounts; } } public function getLines(): array { if (null === $this->_lines && $this->exists()) { $em = EntityManager::getInstance(Line::class); $this->_lines = $em->all('SELECT * FROM @TABLE WHERE id_transaction = ? ORDER BY id;', $this->id); } elseif (null === $this->_lines) { $this->_lines = []; |
︙ | ︙ | |||
250 251 252 253 254 255 256 257 258 259 260 261 262 263 | $type = $this->getTypesDetails()[$this->type]; return [ $type->accounts[0]->position == 'credit' ? $credit : $debit, $type->accounts[1]->position == 'credit' ? $credit : $debit, ]; } /* public function getHash() { if (!$this->id_year) { throw new \LogicException('Il n\'est pas possible de hasher un mouvement qui n\'est pas associé à un exercice'); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | $type = $this->getTypesDetails()[$this->type]; return [ $type->accounts[0]->position == 'credit' ? $credit : $debit, $type->accounts[1]->position == 'credit' ? $credit : $debit, ]; } /** * Creates a new Transaction entity (not saved) from an existing one, * trying to adapt to a different chart if possible * @param int $id * @param Year $year Target year * @return Transaction */ public function duplicate(Year $year): Transaction { $new = new Transaction; $copy = ['type', 'status', 'label', 'notes', 'reference', 'date']; foreach ($copy as $field) { $new->$field = $this->$field; } $copy = ['credit', 'debit', 'id_account', 'label', 'reference']; $lines = DB::getInstance()->get('SELECT l.credit, l.debit, l.label, l.reference, b.id AS id_account FROM acc_transactions_lines l INNER JOIN acc_accounts a ON a.id = l.id_account LEFT JOIN acc_accounts b ON b.code = a.code AND b.id_chart = ? WHERE l.id_transaction = ?;', $year->chart()->id, $this->id() ); foreach ($lines as $l) { $line = new Line; foreach ($copy as $field) { $line->$field = $l->$field; } $new->addLine($line); } return $new; } /* public function getHash() { if (!$this->id_year) { throw new \LogicException('Il n\'est pas possible de hasher un mouvement qui n\'est pas associé à un exercice'); } |
︙ | ︙ | |||
330 331 332 333 334 335 336 | { $line->id_transaction = $this->id(); $line->save(); } foreach ($this->_old_lines as $line) { | > | > | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | { $line->id_transaction = $this->id(); $line->save(); } foreach ($this->_old_lines as $line) { if ($line->exists()) { $line->delete(); } } // Remove flag if (!$exists && $this->_related) { $this->_related->markPaid(); $this->_related->save(); } |
︙ | ︙ |
Modified src/templates/acc/transactions/details.tpl from [0098f837e0] to [b3d4a382f1].
1 2 | {include file="admin/_head.tpl" title="Écriture n°%d"|args:$transaction.id current="acc"} | < > > > > < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | {include file="admin/_head.tpl" title="Écriture n°%d"|args:$transaction.id current="acc"} <nav class="tabs"> {if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE)} <aside>{linkbutton href="new.php?copy=%d"|args:$transaction.id shape="plus" label="Dupliquer cette écriture"}</aside> {/if} {if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_ADMIN) && !$transaction->validated && !$tr_year->closed} <ul> <li><a href="edit.php?id={$transaction.id}">Modifier cette écriture</a></li> <li><a href="delete.php?id={$transaction.id}">Supprimer cette écriture</a></li> </ul> {/if} </nav> {if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE) && $transaction.status & $transaction::STATUS_WAITING} <div class="block alert"> <form method="post" action="{$self_url}"> {if $transaction.type == $transaction::TYPE_DEBT} <h3>Dette en attente</h3> {linkbutton shape="check" label="Enregistrer le règlement de cette dette" href="!acc/transactions/new.php?payoff_for=%d"|args:$transaction.id} |
︙ | ︙ |
Modified src/templates/acc/transactions/new.tpl from [49e96a9c33] to [91b454b44d].
︙ | ︙ | |||
64 65 66 67 68 69 70 | <legend>{$type.label}</legend> {if $type.id == $transaction::TYPE_ADVANCED} {* Saisie avancée *} {include file="acc/transactions/_lines_form.tpl" chart_id=$current_year.id_chart} {else} <dl> {foreach from=$type.accounts key="key" item="account"} | > | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | <legend>{$type.label}</legend> {if $type.id == $transaction::TYPE_ADVANCED} {* Saisie avancée *} {include file="acc/transactions/_lines_form.tpl" chart_id=$current_year.id_chart} {else} <dl> {foreach from=$type.accounts key="key" item="account"} <?php $selected = $types_accounts[$key] ?? null; ?> {input type="list" target="acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:$account.targets_string,$chart_id name="account_%d_%d"|args:$type.id,$key label=$account.label required=1 default=$selected} {/foreach} </dl> {/if} </fieldset> {/foreach} {/if} |
︙ | ︙ |
Modified src/www/admin/acc/transactions/new.php from [d8191985b4] to [c93d48adea].
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 | <?php namespace Garradin; use Garradin\Entities\Accounting\Account; use Garradin\Entities\Accounting\Transaction; use Garradin\Entities\Files\File; use Garradin\Accounting\Years; require_once __DIR__ . '/../_inc.php'; $session->requireAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE); if (!CURRENT_YEAR_ID) { Utils::redirect(ADMIN_URL . 'acc/years/?msg=OPEN'); } $chart = $current_year->chart(); $accounts = $chart->accounts(); $transaction = new Transaction; $lines = [[], []]; $amount = 0; $payoff_for = qg('payoff_for') ?: f('payoff_for'); $date = new \DateTime; if ($session->get('acc_last_date')) { $date = \DateTime::createFromFormat('!d/m/Y', $session->get('acc_last_date')); } | > > > > > > > > > > > > > > > > > > > | 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 | <?php namespace Garradin; use Garradin\Entities\Accounting\Account; use Garradin\Entities\Accounting\Transaction; use Garradin\Entities\Files\File; use Garradin\Accounting\Transactions; use Garradin\Accounting\Years; require_once __DIR__ . '/../_inc.php'; $session->requireAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE); if (!CURRENT_YEAR_ID) { Utils::redirect(ADMIN_URL . 'acc/years/?msg=OPEN'); } $chart = $current_year->chart(); $accounts = $chart->accounts(); $transaction = new Transaction; $lines = [[], []]; $amount = 0; $payoff_for = qg('payoff_for') ?: f('payoff_for'); $types_accounts = null; // Duplicate transaction if (qg('copy')) { $old = Transactions::get((int)qg('copy')); $transaction = $old->duplicate($current_year); $lines = $transaction->getLinesWithAccounts(); $payoff_for = null; $amount = $transaction->getLinesCreditSum(); $types_accounts = $transaction->getTypesAccounts(); $transaction->resetLines(); foreach ($lines as $k => &$line) { $line->account = [$line->id_account => sprintf('%s — %s', $line->account_code, $line->account_name)]; } unset($line); } $date = new \DateTime; if ($session->get('acc_last_date')) { $date = \DateTime::createFromFormat('!d/m/Y', $session->get('acc_last_date')); } |
︙ | ︙ | |||
86 87 88 89 90 91 92 | Utils::redirect(Utils::getSelfURI(false) . '?ok=' . $transaction->id()); } catch (UserException $e) { $form->addError($e->getMessage()); } } | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | Utils::redirect(Utils::getSelfURI(false) . '?ok=' . $transaction->id()); } catch (UserException $e) { $form->addError($e->getMessage()); } } $tpl->assign(compact('transaction', 'payoff_for', 'amount', 'lines', 'types_accounts')); $tpl->assign('payoff_targets', implode(':', [Account::TYPE_BANK, Account::TYPE_CASH, Account::TYPE_OUTSTANDING])); $tpl->assign('ok', (int) qg('ok')); $tpl->assign('types_details', Transaction::getTypesDetails()); $tpl->assign('chart_id', $chart->id()); $tpl->assign('analytical_accounts', ['' => '-- Aucun'] + $accounts->listAnalytical()); $tpl->display('acc/transactions/new.tpl'); |