Overview
Comment:Fonctionnalité rapprochement bancaire
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2fe1c3aa3e7a6d08562910c620a1f24e0b974b4b
User & Date: bohwaz on 2015-02-18 19:16:16
Other Links: manifest | tags
Context
2015-02-19
06:52
Gestion des listes à cocher/décocher plus propre (et passage de l'indentation en tabs) check-in: 9e3b4eda67 user: bohwaz tags: trunk
2015-02-18
19:16
Fonctionnalité rapprochement bancaire check-in: 2fe1c3aa3e user: bohwaz tags: trunk
18:33
Page qui n'existe plus check-in: 12a1739463 user: bohwaz tags: trunk
Changes

Modified src/include/data/0.7.0.sql from [cbca4aa3a3] to [03c2810d89].

2
3
4
5
6
7
8








9
10
11
12
13
14
15
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);









CREATE TABLE fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NOT NULL, -- Type MIME







>
>
>
>
>
>
>
>







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id),
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    auteur INTEGER NOT NULL REFERENCES membres (id)
);

CREATE TABLE fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NOT NULL, -- Type MIME

Modified src/include/data/schema.sql from [52605cc884] to [7deb0e0ac2].

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
319
320
321
322
323
324
325








326
327
328
329
330
331
332
-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

/*
CREATE TABLE wiki_fichiers (
    id INTEGER PRIMARY KEY,
    id_page INTEGER NOT NULL,
    nom TEXT,
    hash TEXT,

    FOREIGN KEY (id_page) REFERENCES wiki_pages (id) -- Clé externe obligatoire
);

CREATE INDEX wiki_fichiers_id_page ON wiki_fichiers (id_page);

CREATE TABLE wiki_suivi
-- Suivi des pages
(
    id_membre INTEGER NOT NULL,
    id_page INTEGER NOT NULL,

    PRIMARY KEY (id_membre, id_page),
................................................................................
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);









CREATE TABLE fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NOT NULL, -- Type MIME







<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>







164
165
166
167
168
169
170











171
172
173
174
175
176
177
...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

/*











CREATE TABLE wiki_suivi
-- Suivi des pages
(
    id_membre INTEGER NOT NULL,
    id_page INTEGER NOT NULL,

    PRIMARY KEY (id_membre, id_page),
................................................................................
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id),
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    auteur INTEGER NOT NULL REFERENCES membres (id)
);

CREATE TABLE fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NOT NULL, -- Type MIME

Modified src/include/lib/Garradin/Compta/Exercices.php from [f31307da50] to [d46db9407d].

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
        return $db->simpleQuerySingle('SELECT *, strftime(\'%s\', debut) AS debut,
            strftime(\'%s\', fin) AS fin FROM compta_exercices WHERE id = ?;', true, (int)$id);
    }

    public function getCurrent()
    {
        $db = DB::getInstance();
        return $db->querySingle('SELECT *, strftime(\'%s\', debut) AS debut, strftime(\'%s\', fin) FROM compta_exercices
            WHERE cloture = 0 LIMIT 1;', true);
    }

    public function getCurrentId()
    {
        $db = DB::getInstance();
        return $db->querySingle('SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1;');







|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
        return $db->simpleQuerySingle('SELECT *, strftime(\'%s\', debut) AS debut,
            strftime(\'%s\', fin) AS fin FROM compta_exercices WHERE id = ?;', true, (int)$id);
    }

    public function getCurrent()
    {
        $db = DB::getInstance();
        return $db->querySingle('SELECT *, strftime(\'%s\', debut) AS debut, strftime(\'%s\', fin) AS fin FROM compta_exercices
            WHERE cloture = 0 LIMIT 1;', true);
    }

    public function getCurrentId()
    {
        $db = DB::getInstance();
        return $db->querySingle('SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1;');

Added src/include/lib/Garradin/Compta/Rapprochement.php version [426c8449ed].











































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
61
62
63
64
65
66
67
68
69
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;
use \Garradin\Compta\Journal;
use \Garradin\Compta\Comptes_Bancaires;

class Rapprochement
{
    public function getJournal($compte, $debut, $fin)
    {
        $db = DB::getInstance();

        $exercice = $db->querySingle('SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1;');

        $query = '
        	SELECT j.*, strftime(\'%s\', j.date) AS date, 
            	(CASE WHEN j.compte_debit = :compte THEN j.montant ELSE -(j.montant) END) AS solde,
            	r.date
            FROM compta_journal AS j
            	LEFT JOIN compta_rapprochement AS r ON r.operation = j.id
            WHERE (compte_debit = :compte OR compte_credit = :compte) AND id_exercice = :exercice
            	AND j.date >= :debut AND j.date <= :fin
            ORDER BY date ASC;';

        $result = $db->simpleStatementFetch($query, DB::ASSOC, [
        	'compte'	=>	$compte,
        	'debut'		=>	$debut,
        	'fin'		=>	$fin,
        	'exercice'	=>	$exercice
        ]);

        $solde = 0.0;

        foreach ($result as &$row)
        {
            $solde += $row['solde'];
            $row['solde'] = $solde;
        }

        return $result;
    }

    public function record($compte, $operations, $auteur)
    {
    	if (!is_array($operations))
    	{
    		throw new \UnexpectedValueException('$operations doit être un tableau.');
    	}

    	$db = DB::getInstance();
    	$db->exec('BEGIN;');
    	$st = $db->prepare('INSERT OR REPLACE INTO compta_rapprochement (operation, auteur) 
    		VALUES (:operation, :auteur);');
    	$st->bindValue(':auteur', (int)$auteur, \SQLITE3_INTEGER);

    	foreach ($operations as $row)
    	{
    		$st->bindValue(':operation', (int)$row, \SQLITE3_INTEGER);
    		$st->execute();
    	}

    	$db->exec('END;');
    	return true;
    }
}

Modified src/include/lib/Garradin/DB.php from [7406e12909] to [7e56a5c401].

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    }

    public function getArgType($arg, $name = '')
    {
        switch (gettype($arg))
        {
            case 'double':
                return SQLITE3_FLOAT;
            case 'integer':
            case 'boolean':
                return SQLITE3_INTEGER;
            case 'NULL':
                return SQLITE3_NULL;
            case 'string':
                return SQLITE3_TEXT;
            default:
                throw new \InvalidArgumentException('Argument '.$name.' is of invalid type '.gettype($arg));
        }
    }

    public function simpleStatement($query, $args = [])
    {
................................................................................

    public function escapeAuto($value, $name = '')
    {
        $type = $this->getArgType($value, $name);

        switch ($type)
        {
            case SQLITE3_FLOAT:
                return floatval($value);
            case SQLITE3_INTEGER:
                return intval($value);
            case SQLITE3_NULL:
                return 'NULL';
            case SQLITE3_TEXT:
                return '\'' . $this->escapeString($value) . '\'';
        }
    }

    /**
     * Simple INSERT query
     */







|


|

|

|







 







|

|

|

|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    }

    public function getArgType($arg, $name = '')
    {
        switch (gettype($arg))
        {
            case 'double':
                return \SQLITE3_FLOAT;
            case 'integer':
            case 'boolean':
                return \SQLITE3_INTEGER;
            case 'NULL':
                return \SQLITE3_NULL;
            case 'string':
                return \SQLITE3_TEXT;
            default:
                throw new \InvalidArgumentException('Argument '.$name.' is of invalid type '.gettype($arg));
        }
    }

    public function simpleStatement($query, $args = [])
    {
................................................................................

    public function escapeAuto($value, $name = '')
    {
        $type = $this->getArgType($value, $name);

        switch ($type)
        {
            case \SQLITE3_FLOAT:
                return floatval($value);
            case \SQLITE3_INTEGER:
                return intval($value);
            case \SQLITE3_NULL:
                return 'NULL';
            case \SQLITE3_TEXT:
                return '\'' . $this->escapeString($value) . '\'';
        }
    }

    /**
     * Simple INSERT query
     */

Modified src/templates/admin/compta/banques/rapprocher.tpl from [c2cc21d617] to [d798562d82].

2
3
4
5
6
7
8















9












































10

<ul class="actions">
    <li><a href="{$www_url}admin/compta/banques/">Comptes bancaires</a></li>
    <li><a href="{$www_url}admin/compta/comptes/journal.php?id={Garradin\Compta\Comptes::CAISSE}&amp;suivi">Journal de caisse</a></li>
    <li class="current"><a href="{$admin_url}compta/banques/rapprochement.php?id={$compte.id|escape}">Rapprochement</a></li>
</ul>





























































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







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

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

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
61
62
63
64
65
66
67
68
69

<ul class="actions">
    <li><a href="{$www_url}admin/compta/banques/">Comptes bancaires</a></li>
    <li><a href="{$www_url}admin/compta/comptes/journal.php?id={Garradin\Compta\Comptes::CAISSE}&amp;suivi">Journal de caisse</a></li>
    <li class="current"><a href="{$admin_url}compta/banques/rapprochement.php?id={$compte.id|escape}">Rapprochement</a></li>
</ul>

<form method="get" action="{$self_url|escape}">
    <fieldset>
        <legend>Période de rapprochement</legend>
        <dl>
            <dt><label for="f_debut">Début</label></dt>
            <dd><input type="date" name="debut" id="f_debut" value="{form_field name='debut' default=$debut}" /></dd>
            <dt><label for="f_fin">Fin</label></dt>
            <dd><input type="date" name="fin" id="f_fin" value="{form_field name='fin' default=$fin}" /></dd>
        </dl>
        <p>
            <input type="hidden" name="id" value="{$compte.id|escape}" />
            <input type="submit" value="Afficher" />
        </p>
    </fieldset>
</form>

<table class="list">
    <colgroup>
        <col width="3%" />
        <col width="3%" />
        <col width="12%" />
        <col width="10%" />
        <col width="12%" />
        <col />
    </colgroup>
    <thead>
        <tr>
            <td></td>
            <td></td>
            <td>Date</td>
            <td>Montant</td>
            <td>Solde cumulé</td>
            <th>Libellé</th>
        </tr>
    </thead>
    <tbody>
    {foreach from=$journal item="ligne"}
        <tr>
            <td class="num"><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id|escape}">{$ligne.id|escape}</a></td>
            <td class="actions">
            {if $user.droits.compta >= Garradin\Membres::DROIT_ADMIN}
                <a class="icn" href="{$admin_url}compta/operations/modifier.php?id={$ligne.id|escape}" title="Modifier cette opération">✎</a>
            {/if}
            </td>
            <td>{$ligne.date|date_fr:'d/m/Y'|escape}</td>
            <td>{if $ligne.compte_credit == $compte.id}-{else}+{/if}{$ligne.montant|html_money}</td>
            <td>{$ligne.solde|html_money}</td>
            <th>{$ligne.libelle|escape}</th>
        </tr>
    {/foreach}
    </tbody>
    <tfoot>
        <tr>
            <td colspan="3"></td>
            <th>Solde</th>
            <td colspan="2">{*{$solde|html_money} {$config.monnaie|escape}*}</td>
        </tr>
    </tfoot>
</table>

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

Added src/www/admin/compta/banques/rapprocher.php version [84f2a86f78].































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
namespace Garradin;

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

if ($user['droits']['compta'] < Membres::DROIT_ADMIN)
{
    throw new UserException("Vous n'avez pas le droit d'accéder à cette page.");
}

$banques = new Compta\Comptes_Bancaires;
$rapprochement = new Compta\Rapprochement;
$exercices = new Compta\Exercices;
$exercice = $exercices->getCurrent();

$compte = $banques->get(Utils::get('id'));

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

$error = false;

if (Utils::post('save'))
{
    if (!Utils::CSRF_check('compta_rapprocher_' . $compte['id']))
    {
        $error = 'Une erreur est survenue, merci de renvoyer le formulaire.';
    }
    else
    {
        try
        {
            $rapprochement->record($compte['id'], Utils::post('rapprocher'), $user['id']);
            Utils::redirect('/admin/compta/banques/rapprocher.php?id=');
        }
        catch (UserException $e)
        {
            $error = $e->getMessage();
        }
	}
}

$debut = Utils::get('debut');
$fin = Utils::get('fin');

if ($debut && $fin)
{
    if (!Utils::checkDate($debut) || !Utils::checkDate($fin))
    {
        $error = 'La date donnée est invalide.';
        $debut = $fin = false;
    }
    else if (strtotime($debut) < $exercice['debut'])
    {
        $debut = date('Y-m-d', $exercice['debut']);
    }
    else if (strtotime($fin) > $exercice['fin'])
    {
        $fin = date('Y-m-d', $exercice['fin']);
    }
}

if (!$debut || !$fin)
{
    $date = $exercice['fin'];
    $debut = date('Y-m-01', $date);
    $fin = date('Y-m-31', $date);
}

$tpl->assign('compte', $compte);
$tpl->assign('debut', $debut);
$tpl->assign('fin', $fin);
$tpl->assign('journal', $rapprochement->getJournal($compte['id'], $debut, $fin));

$tpl->assign('error', $error);

$tpl->display('admin/compta/banques/rapprocher.tpl');