Comment: | Add more graphs |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dev |
Files: | files | file ages | folders |
SHA1: |
fa963fe8347bf63a663e9b7a9088fc25 |
User & Date: | bohwaz on 2020-10-17 17:01:58 |
Other Links: | branch diff | manifest | tags |
2020-10-18
| ||
10:45 | Move account import to Accounts::import check-in: ee3811b076 user: bohwaz tags: dev | |
2020-10-17
| ||
17:01 | Add more graphs check-in: fa963fe834 user: bohwaz tags: dev | |
15:55 | Try to match accounts between old and new chart check-in: e95ce263c4 user: bohwaz tags: dev | |
Modified src/VERSION from [34c6fceca7] to [4a93211522].
|
| < > | 1 | 1.0.0-alpha1 |
Modified src/include/lib/Garradin/Accounting/Graph.php from [65ca470418] to [857699aed3].
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 | <?php namespace Garradin\Accounting; use Garradin\Entities\Accounting\Account; use Garradin\Entities\Accounting\Line; use Garradin\Entities\Accounting\Transaction; use Garradin\Utils; use Garradin\Config; use Garradin\DB; use const Garradin\ADMIN_COLOR1; use KD2\DB\EntityManager; use KD2\Graphics\SVG\Plot; use KD2\Graphics\SVG\Plot_Data; use KD2\Graphics\SVG\Pie; use KD2\Graphics\SVG\Pie_Data; class Graph { const PLOT_TYPES = [ 'assets' => [ 'Total' => ['type' => [Account::TYPE_BANK, Account::TYPE_CASH, Account::TYPE_OUTSTANDING]], 'Banques' => ['type' => Account::TYPE_BANK], 'Caisses' => ['type' => Account::TYPE_CASH], 'En attente' => ['type' => Account::TYPE_OUTSTANDING], ], | > > > > > > > > > > | 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 | <?php namespace Garradin\Accounting; use Garradin\Entities\Accounting\Account; use Garradin\Entities\Accounting\Line; use Garradin\Entities\Accounting\Transaction; use Garradin\Utils; use Garradin\Config; use Garradin\DB; use const Garradin\ADMIN_COLOR1; use const Garradin\ADMIN_URL; use KD2\DB\EntityManager; use KD2\Graphics\SVG\Plot; use KD2\Graphics\SVG\Plot_Data; use KD2\Graphics\SVG\Pie; use KD2\Graphics\SVG\Pie_Data; class Graph { const URL_LIST = [ ADMIN_URL . 'acc/reports/graph_plot.php?type=assets&year=%s' => 'Évolution banques et caisses', ADMIN_URL . 'acc/reports/graph_plot.php?type=result&year=%s' => 'Évolution dépenses et recettes', ADMIN_URL . 'acc/reports/graph_plot.php?type=debts&year=%s' => 'Évolution dettes et créances', ADMIN_URL . 'acc/reports/graph_pie.php?type=revenue&year=%s' => 'Répartition recettes', ADMIN_URL . 'acc/reports/graph_pie.php?type=expense&year=%s' => 'Répartition dépenses', ADMIN_URL . 'acc/reports/graph_pie.php?type=assets&year=%s' => 'Répartition actif', ]; const PLOT_TYPES = [ 'assets' => [ 'Total' => ['type' => [Account::TYPE_BANK, Account::TYPE_CASH, Account::TYPE_OUTSTANDING]], 'Banques' => ['type' => Account::TYPE_BANK], 'Caisses' => ['type' => Account::TYPE_CASH], 'En attente' => ['type' => Account::TYPE_OUTSTANDING], ], |
︙ | ︙ | |||
37 38 39 40 41 42 43 | const PIE_TYPES = [ 'revenue' => ['position' => Account::REVENUE], 'expense' => ['position' => Account::EXPENSE], 'assets' => ['type' => [Account::TYPE_BANK, Account::TYPE_CASH, Account::TYPE_OUTSTANDING]], ]; | | > | | | > > > | | 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 | const PIE_TYPES = [ 'revenue' => ['position' => Account::REVENUE], 'expense' => ['position' => Account::EXPENSE], 'assets' => ['type' => [Account::TYPE_BANK, Account::TYPE_CASH, Account::TYPE_OUTSTANDING]], ]; const WEEKLY_INTERVAL = 604800; // 7 days const MONTHLY_INTERVAL = 2635200; // 1 month static public function plot(string $type, array $criterias, int $interval = self::WEEKLY_INTERVAL, int $width = 700) { if (!array_key_exists($type, self::PLOT_TYPES)) { throw new \InvalidArgumentException('Unknown type'); } $plot = new Plot($width, 300); $lines = self::PLOT_TYPES[$type]; $data = []; foreach ($lines as $label => $line_criterias) { $line_criterias = array_merge($criterias, $line_criterias); $sums = Reports::getSumsByInterval($line_criterias, $interval); // Invert sums for banks, cash, etc. if ('assets' === $type) { $sums = array_map(function ($v) { return $v * -1; }, $sums); } elseif ('result' === $type) { $sums = array_map('abs', $sums); } $sums = array_map(function ($v) { return (int)$v/100; }, $sums); $graph = new Plot_Data($sums); $graph->title = $label; $data[] = $graph; } if (count($data)) { $labels = []; foreach ($data[0]->get() as $k=>$v) { $date = new \DateTime('@' . ($k * $interval)); $labels[] = Utils::date_fr('M y', $date); } $plot->setLabels($labels); $i = 0; $colors = self::getColors(); |
︙ | ︙ | |||
101 102 103 104 105 106 107 | static public function pie(string $type, array $criterias) { if (!array_key_exists($type, self::PIE_TYPES)) { throw new \InvalidArgumentException('Unknown type'); } | | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | static public function pie(string $type, array $criterias) { if (!array_key_exists($type, self::PIE_TYPES)) { throw new \InvalidArgumentException('Unknown type'); } $pie = new Pie(700, 300); $pie_criterias = self::PIE_TYPES[$type]; $data = Reports::getClosingSumsWithAccounts(array_merge($criterias, $pie_criterias), 'ABS(sum) DESC'); $others = 0; $colors = self::getColors(); $max = count($colors); $i = 0; foreach ($data as $row) |
︙ | ︙ | |||
141 142 143 144 145 146 147 | $c1 = $config->get('couleur1') ?: ADMIN_COLOR1; list($h, $s, $v) = Utils::rgbToHsv($c1); $s = 100; $v = 70; $colors = []; | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | $c1 = $config->get('couleur1') ?: ADMIN_COLOR1; list($h, $s, $v) = Utils::rgbToHsv($c1); $s = 100; $v = 70; $colors = []; for ($i = 0; $i < 6; $i++) { $colors[] = sprintf('hsl(%d, %d%%, %d%%)', $h, $s, $v); $h += 20; if ($h > 360) { $h -= 360; } } return $colors; } } |
Modified src/include/lib/Garradin/Accounting/Reports.php from [71a462b127] to [fa005c4ef4].
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 | return implode(' AND ', $where); } static public function getSumsByInterval(array $criterias, int $interval) { $where = self::getWhereClause($criterias); $db = DB::getInstance(); $sql = sprintf('SELECT strftime(\'%%s\', MIN(date)) / %d AS start_interval, strftime(\'%%s\', MAX(date)) / %1$d AS end_interval | > | | | | | > > > > > > > | | 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 | return implode(' AND ', $where); } static public function getSumsByInterval(array $criterias, int $interval) { $where = self::getWhereClause($criterias); $where_interval = !empty($criterias['year']) ? sprintf(' WHERE id_year = %d', $criterias['year']) : ''; $db = DB::getInstance(); $sql = sprintf('SELECT strftime(\'%%s\', MIN(date)) / %d AS start_interval, strftime(\'%%s\', MAX(date)) / %1$d AS end_interval FROM acc_transactions %s;', $interval, $where_interval); extract((array)$db->first($sql)); $out = array_fill_keys(range($start_interval, $end_interval), 0); $sql = sprintf('SELECT strftime(\'%%s\', t.date) / %d AS interval, SUM(l.credit) - SUM(l.debit) AS sum, t.id_year FROM acc_transactions t INNER JOIN acc_transactions_lines l ON l.id_transaction = t.id INNER JOIN acc_accounts a ON a.id = l.id_account WHERE %s GROUP BY %s ORDER BY %3$s;', $interval, $where, isset($criterias['year']) ? 'interval' : 't.id_year'); $data = $db->getGrouped($sql); $sum = 0; $year = null; foreach ($out as $k => &$v) { if (array_key_exists($k, $data)) { $row = $data[$k]; if ($row->id_year != $year) { $sum = 0; $year = $row->id_year; } $sum += $data[$k]->sum; } $v = $sum; } return $out; } |
︙ | ︙ |
Modified src/templates/acc/index.tpl from [f4381d456e] to [8b7980a96b].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {include file="admin/_head.tpl" title="Comptabilité" current="acc"} {foreach from=$years item="year"} <section class="year-infos"> <h2 class="ruler">{$year.label} — Du {$year.start_date|date_fr:'d/m/Y'} au {$year.end_date|date_fr:'d/m/Y'}</h2> <nav class="tabs"> <ul> <li><a href="{$admin_url}acc/reports/journal.php?year={$year.id}">Journal général</a></li> <li><a href="{$admin_url}acc/reports/ledger.php?year={$year.id}">Grand livre</a></li> <li><a href="{$admin_url}acc/reports/trial_balance.php?year={$year.id}">Balance générale</a></li> <li><a href="{$admin_url}acc/reports/statement.php?year={$year.id}">Compte de résultat</a></li> <li><a href="{$admin_url}acc/reports/balance_sheet.php?year={$year.id}">Bilan</a></li> <li><a href="{$admin_url}acc/transactions/search.php?year={$year.id}"><strong>Recherche</strong></a></li> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | {include file="admin/_head.tpl" title="Comptabilité" current="acc"} {foreach from=$years item="year"} <section class="year-infos"> <h2 class="ruler">{$year.label} — Du {$year.start_date|date_fr:'d/m/Y'} au {$year.end_date|date_fr:'d/m/Y'}</h2> <nav class="tabs"> <ul> <li><a href="{$admin_url}acc/reports/graphs.php?year={$year.id}">Graphiques</a></li> <li><a href="{$admin_url}acc/reports/journal.php?year={$year.id}">Journal général</a></li> <li><a href="{$admin_url}acc/reports/ledger.php?year={$year.id}">Grand livre</a></li> <li><a href="{$admin_url}acc/reports/trial_balance.php?year={$year.id}">Balance générale</a></li> <li><a href="{$admin_url}acc/reports/statement.php?year={$year.id}">Compte de résultat</a></li> <li><a href="{$admin_url}acc/reports/balance_sheet.php?year={$year.id}">Bilan</a></li> <li><a href="{$admin_url}acc/transactions/search.php?year={$year.id}"><strong>Recherche</strong></a></li> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} |
︙ | ︙ |
Modified src/templates/acc/reports/_header.tpl from [32154882df] to [31fe879fc1].
1 2 3 4 5 6 7 8 9 10 11 | <div class="year-header"> <nav class="tabs noprint"> <ul> <li{if $current == "journal"} class="current"{/if}><a href="{$admin_url}acc/reports/journal.php?year={$year.id}">Journal général</a></li> <li{if $current == "ledger"} class="current"{/if}><a href="{$admin_url}acc/reports/ledger.php?year={$year.id}">Grand livre</a></li> <li{if $current == "trial_balance"} class="current"{/if}><a href="{$admin_url}acc/reports/trial_balance.php?year={$year.id}">Balance générale</a></li> <li{if $current == "statement"} class="current"{/if}><a href="{$admin_url}acc/reports/statement.php?year={$year.id}">Compte de résultat</a></li> <li{if $current == "balance_sheet"} class="current"{/if}><a href="{$admin_url}acc/reports/balance_sheet.php?year={$year.id}">Bilan</a></li> </ul> </nav> | > | 1 2 3 4 5 6 7 8 9 10 11 12 | <div class="year-header"> <nav class="tabs noprint"> <ul> <li{if $current == "graphs"} class="current"{/if}><a href="{$admin_url}acc/reports/graphs.php?year={$year.id}">Graphiques</a></li> <li{if $current == "journal"} class="current"{/if}><a href="{$admin_url}acc/reports/journal.php?year={$year.id}">Journal général</a></li> <li{if $current == "ledger"} class="current"{/if}><a href="{$admin_url}acc/reports/ledger.php?year={$year.id}">Grand livre</a></li> <li{if $current == "trial_balance"} class="current"{/if}><a href="{$admin_url}acc/reports/trial_balance.php?year={$year.id}">Balance générale</a></li> <li{if $current == "statement"} class="current"{/if}><a href="{$admin_url}acc/reports/statement.php?year={$year.id}">Compte de résultat</a></li> <li{if $current == "balance_sheet"} class="current"{/if}><a href="{$admin_url}acc/reports/balance_sheet.php?year={$year.id}">Bilan</a></li> </ul> </nav> |
︙ | ︙ |
Added src/templates/acc/reports/graphs.tpl version [3b49429080].
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {include file="admin/_head.tpl" title="Graphiques" current="acc"} {include file="acc/reports/_header.tpl" current="graphs"} <section class="year-infos"> <section class="graphs"> {foreach from=$graphs key="url" item="label"} <figure> <img src="{$url|args:$year.id}" alt="" /> <figcaption>{$label}</figcaption> </figure> {/foreach} </section> </section> {include file="admin/_foot.tpl"} |
Modified src/templates/acc/years/index.tpl from [0c5e4eb3eb] to [d94f97225f].
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | {if $session->canAccess('compta', Membres::DROIT_ADMIN)} Merci d'en <a href="{$admin_url}acc/years/new.php">créer un nouveau</a> pour pouvoir saisir des écritures. {/if} </p> {/if} {if !empty($list)} <dl class="list"> {foreach from=$list item="year"} <dt>{$year.label}</dt> <dd class="desc"> {if $year.closed}Clôturé{else}En cours{/if} | Du {$year.start_date|date_fr:'d/m/Y'} au {$year.end_date|date_fr:'d/m/Y'} </dd> <dd class="desc"> | > > > > > > > > > > > > > > | | 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 | {if $session->canAccess('compta', Membres::DROIT_ADMIN)} Merci d'en <a href="{$admin_url}acc/years/new.php">créer un nouveau</a> pour pouvoir saisir des écritures. {/if} </p> {/if} {if !empty($list)} {if count($list) > 1} <section class="year-infos"> <section class="graphs"> <figure> <img src="{$admin_url}acc/reports/graph_plot_all.php?type=result" alt="" /> </figure> <figure> <img src="{$admin_url}acc/reports/graph_plot_all.php?type=assets" alt="" /> </figure> </section> </section> {/if} <dl class="list"> {foreach from=$list item="year"} <dt>{$year.label}</dt> <dd class="desc"> {if $year.closed}Clôturé{else}En cours{/if} | Du {$year.start_date|date_fr:'d/m/Y'} au {$year.end_date|date_fr:'d/m/Y'} </dd> <dd class="desc"> <a href="{$admin_url}acc/reports/graphs.php?year={$year.id}">Graphiques</a> | <a href="{$admin_url}acc/reports/journal.php?year={$year.id}">Journal général</a> | <a href="{$admin_url}acc/reports/ledger.php?year={$year.id}">Grand livre</a> | <a href="{$admin_url}acc/reports/trial_balance.php?year={$year.id}">Balance générale</a> | <a href="{$admin_url}acc/reports/statement.php?year={$year.id}">Compte de résultat</a> | <a href="{$admin_url}acc/reports/balance_sheet.php?year={$year.id}">Bilan</a> </dd> {if $session->canAccess('compta', Membres::DROIT_ADMIN) && !$year.closed} <dd class="actions"> |
︙ | ︙ |
Modified src/www/admin/acc/index.php from [581e2c5f42] to [26b2d4ae1a].
1 2 3 4 5 6 7 8 9 10 11 | <?php namespace Garradin; use Garradin\Accounting\Years; require_once __DIR__ . '/../_inc.php'; $session->requireAccess('compta', Membres::DROIT_ACCES); $years = new Years; | > < < < < < < < < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php namespace Garradin; use Garradin\Accounting\Years; use Garradin\Accounting\Graph; require_once __DIR__ . '/../_inc.php'; $session->requireAccess('compta', Membres::DROIT_ACCES); $years = new Years; $tpl->assign('graphs', Graph::URL_LIST); $tpl->assign('years', $years->listOpen()); $tpl->display('acc/index.tpl'); |
Added src/www/admin/acc/reports/graph_plot_all.php version [c72784090c].
> > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; use Garradin\Accounting\Graph; require_once __DIR__ . '/../_inc.php'; qv(['type' => 'string|required']); header('Content-Type: image/svg+xml'); echo Graph::plot(qg('type'), [], Graph::MONTHLY_INTERVAL, 400); |
Added src/www/admin/acc/reports/graphs.php version [fc9df953bc].
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php namespace Garradin; use Garradin\Accounting\Years; use Garradin\Accounting\Graph; require_once __DIR__ . '/_inc.php'; $session->requireAccess('compta', Membres::DROIT_ACCES); $year = Years::get((int)qg('year')); $tpl->assign('graphs', Graph::URL_LIST); $tpl->assign('year', $year); $tpl->display('acc/reports/graphs.tpl'); |
Modified src/www/admin/static/print.css from [783af76560] to [46b90e6ada].
1 | @page { | | | 1 2 3 4 5 6 7 8 9 | @page { size: A4 portrait; margin: 0; } body { background: #fff; padding: 0; margin: 1cm; |
︙ | ︙ | |||
74 75 76 77 78 79 80 | } td.actions * { display: none; } td.num a { | | > | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | } td.actions * { display: none; } td.num a { border: none; padding: 0; background: none; } a { color: black !important; text-decoration: none; } /* Don't repeat the table footer on every printed page */ table tfoot{ display:table-row-group; } |