Overview
SHA1:0b5335059737d55413a5b24020eae919d10ac297
Date: 2019-01-28 16:58:42
User: bohwaz
Comment:Merge trunk vers dev
Timelines: family | ancestors | descendants | both | dev
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2019-01-29
12:41
[4a7b339386] Préparation pour refonte compta (user: bohwaz, tags: dev)
2019-01-28
16:58
[0b53350597] Merge trunk vers dev (user: bohwaz, tags: dev)
14:11
[c48cf081fa] Version 0.9.2 (user: bohwaz, tags: trunk, stable, 0.9.2)
2019-01-22
11:37
[344c04b375] Merge trunk avec dev (user: bohwaz, tags: dev)
Changes

Modified debian/config.debian.php from [d4c3b1b5ce] to [2a98e1b5ea].

49
50
51
52
53
54
55
56
57
58
59
60
61
62












63
64
65
	{
		$last_sqlite = trim($_ENV['GARRADIN_STANDALONE']);
	}
	else if (file_exists($last_file))
	{
		$last_sqlite = trim(file_get_contents($last_file));
	}
	else 
	{
		$last_sqlite = $_ENV['XDG_DATA_HOME'] . '/garradin/association.sqlite';
	}

	file_put_contents($last_file, $last_sqlite);
	












	define('Garradin\DB_FILE', $last_sqlite);
	define('Garradin\LOCAL_LOGIN', 1);
}







|





|
>
>
>
>
>
>
>
>
>
>
>
>



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
	{
		$last_sqlite = trim($_ENV['GARRADIN_STANDALONE']);
	}
	else if (file_exists($last_file))
	{
		$last_sqlite = trim(file_get_contents($last_file));
	}
	else
	{
		$last_sqlite = $_ENV['XDG_DATA_HOME'] . '/garradin/association.sqlite';
	}

	file_put_contents($last_file, $last_sqlite);

	$secret_file = $_ENV['XDG_CONFIG_HOME'] . '/garradin/secret';

	if (!file_exists($secret_file))
	{
		$random = function_exists('random_bytes') ? random_bytes(64) : mt_rand();
		$random = sha1($random . $secret_file);

		file_put_contents($secret_file, $random);
	}

	define('Garradin\SECRET_KEY', trim(file_get_contents($secret_file)));

	define('Garradin\DB_FILE', $last_sqlite);
	define('Garradin\LOCAL_LOGIN', 1);
}

Modified debian/garradin from [872310890e] to [f3db96af25].

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
..
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
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
81
82
83
84
85
86
87


88
89
90
91
92
93
94



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/sh

ROOT=/usr/share/garradin/www
#ROOT=~/fossil/garradin/src/www
ROUTER=${ROOT}/_route.php
PORT=8088
ADDRESS="127.0.0.1"
VERBOSE=0




# Execute getopt
ARGS=`getopt -o "p:vh" -l "port:,verbose,help" -n "garradin" -- "$@"`
 
# Bad arguments
if [ $? -ne 0 ];
then
  exit 1
fi
 
# A little magic
eval set -- "$ARGS"

# Now go through all the options
while true;
do
  case "$1" in
................................................................................

    -h|--help)
      cat <<EOF
Usage : $0 [COMMANDE] [PROJET]

Où COMMANDE peut être :

        server [-p|--port PORT] 
                Démarre un serveur web Garradin sur le port spécifié
                (ou sur le port 8000 par défaut)

        ui [-p|--port PORT]
                Idem que 'server' mais démarre ensuite le navigateur web par défaut
                et connecte automatiquement avec le premier administrateur
                de l'association.

Si aucune COMMANDE n'est donnée, Garradin utilisera 'ui' par défaut.

PROJET est le chemin menant à un projet Garradin précis 
        (fichier .garradin.sqlite). Si aucun projet n'est indiqué, le 
        dernier projet ouvert sera rouvert. Si aucun projet n'a jamais été
        ouvert un nouveau projet sera créé.

Options :

        -p|--port PORT
                Spécifie le port pour le mode ui ou le mode serveur.
................................................................................
                Affiche les requêtes reçues sur le serveur web.

        -h|--help
                Affiche ce message.
EOF
      exit
      shift;;
 
    --)
      shift
      break;;
  esac
done

CMD="$1"
................................................................................

PROJECT="$2"

[ "$PROJECT" = "" ] && PROJECT="1"

export GARRADIN_STANDALONE="$PROJECT"



[ $VERBOSE = 1 ] && {
    php -S ${ADDRESS}:${PORT} -t ${ROOT} -d variables_order=EGPCS ${ROUTER} &
} || {
    php -S ${ADDRESS}:${PORT} -t ${ROOT} -d variables_order=EGPCS ${ROUTER} > /dev/null 2>&1 &
}

php_pid=$!



sleep .5

[ "$CMD" = "ui" ] && {
    URL="http://${ADDRESS}:${PORT}/"
    [ "$DISPLAY" != "" ] && {
        x-www-browser ${URL} &
    } || {
        www-browser ${URL} &
    }

    wait $!
    kill $php_pid
} || {
    wait $php_pid
}





|


>
>
>



|





|







 







|

|








|
|







 







|







 







>
>







>
>
>



|





<
<
<



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
..
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
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111



112
113
114
#!/bin/sh

ROOT=/usr/share/garradin/www
#ROOT=~/fossil/garradin/src/www
ROUTER=${ROOT}/_route.php
PORT=8081
ADDRESS="127.0.0.1"
VERBOSE=0
PID_FILE="${XDG_RUNTIME_DIR}/garradin/pid"

[ ! -d `dirname $PID_FILE` ] && mkdir -p `dirname $PID_FILE`

# Execute getopt
ARGS=`getopt -o "p:vh" -l "port:,verbose,help" -n "garradin" -- "$@"`

# Bad arguments
if [ $? -ne 0 ];
then
  exit 1
fi

# A little magic
eval set -- "$ARGS"

# Now go through all the options
while true;
do
  case "$1" in
................................................................................

    -h|--help)
      cat <<EOF
Usage : $0 [COMMANDE] [PROJET]

Où COMMANDE peut être :

        server [-p|--port PORT]
                Démarre un serveur web Garradin sur le port spécifié
                (ou sur le port 8081 par défaut)

        ui [-p|--port PORT]
                Idem que 'server' mais démarre ensuite le navigateur web par défaut
                et connecte automatiquement avec le premier administrateur
                de l'association.

Si aucune COMMANDE n'est donnée, Garradin utilisera 'ui' par défaut.

PROJET est le chemin menant à un projet Garradin précis
        (fichier .garradin.sqlite). Si aucun projet n'est indiqué, le
        dernier projet ouvert sera rouvert. Si aucun projet n'a jamais été
        ouvert un nouveau projet sera créé.

Options :

        -p|--port PORT
                Spécifie le port pour le mode ui ou le mode serveur.
................................................................................
                Affiche les requêtes reçues sur le serveur web.

        -h|--help
                Affiche ce message.
EOF
      exit
      shift;;

    --)
      shift
      break;;
  esac
done

CMD="$1"
................................................................................

PROJECT="$2"

[ "$PROJECT" = "" ] && PROJECT="1"

export GARRADIN_STANDALONE="$PROJECT"

[ -f $PID_FILE ] && kill `cat $PID_FILE` > /dev/null 2>&1 && rm -f $PID_FILE

[ $VERBOSE = 1 ] && {
    php -S ${ADDRESS}:${PORT} -t ${ROOT} -d variables_order=EGPCS ${ROUTER} &
} || {
    php -S ${ADDRESS}:${PORT} -t ${ROOT} -d variables_order=EGPCS ${ROUTER} > /dev/null 2>&1 &
}

php_pid=$!

echo $php_pid > $PID_FILE

sleep .5

[ "$CMD" = "ui" ] && {
    URL="http://${ADDRESS}:${PORT}/admin/"
    [ "$DISPLAY" != "" ] && {
        x-www-browser ${URL} &
    } || {
        www-browser ${URL} &
    }



} || {
    wait $php_pid
}

Added debian/garradin.desktop version [0ea3e7ac4d].













>
>
>
>
>
>
1
2
3
4
5
6
[Desktop Entry]
Name=Garradin
Exec=garradin
Icon=garradin
Type=Application
Categories=Office;Finance;Database

Added debian/garradin.menu version [6b9a082e8a].







>
>
>
1
2
3
?package(garradin):needs="X11" section="Applications/Office"\
  title="Garradin" command="/usr/bin/garradin"\
  icon="/usr/share/garradin/garradin.png"

Added debian/garradin.png version [ed09b910ce].

cannot compute difference between binary files

Modified debian/makedeb.sh from [b70d32f694] to [242f467b69].

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
...
134
135
136
137
138
139
140

141
142
143

DEB_REV=${1-1} # .deb package build/revision number.
PACKAGE_DEBNAME=garradin
THISDIR=${PWD}

DEB_ARCH_NAME=all

SRCDIR=$(cd ..; pwd)/src





SRCDIR='/tmp/garradin-0.9.0'

test -e ${SRCDIR} || {
    echo "This script must be run from a BUILT copy of the source tree."
    exit 1
}

DEBROOT=$PWD/deb.tmp
test -d ${DEBROOT} && rm -fr ${DEBROOT}
................................................................................

DEBLOCALPREFIX=${DEBROOT}/usr
BINDIR=${DEBLOCALPREFIX}/bin
mkdir -p ${BINDIR}
mkdir -p ${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}
cp ${THISDIR}/garradin ${BINDIR}






CODEDIR=${DEBLOCALPREFIX}/share/${PACKAGE_DEBNAME}
mkdir -p ${CODEDIR}
cp -r ${SRCDIR}/* ${CODEDIR}
cp ${THISDIR}/config.debian.php ${CODEDIR}/config.local.php
rm -rf ${CODEDIR}/*.sqlite ${CODEDIR}/cache ${CODEDIR}/www/squelettes


# Cleaning files that will be copied to /usr/share/doc
rm -f ${CODEDIR}/{README,COPYING}

cd $DEBROOT || {
    echo "Debian dest dir [$DEBROOT] not found. :("
    exit 2
}

rm -fr DEBIAN
mkdir DEBIAN

PACKAGE_VERSION=`cat ${SRCDIR}/VERSION`
PACKAGE_DEB_VERSION=${PACKAGE_VERSION}-${DEB_REV}
DEBFILE=${THISDIR}/${PACKAGE_DEBNAME}-${PACKAGE_DEB_VERSION}-dev-${DEB_ARCH_NAME}.deb
PACKAGE_TIME=$(/bin/date)

rm -f ${DEBFILE}
echo "Creating .deb package [${DEBFILE}]..."

................................................................................
    dpkg-deb --info ${DEBFILE}
}

cd - >/dev/null
true && {
    echo "Cleaning up..."
    rm -fr ${DEBROOT}

}

echo "Done :)"







|
>
>
>
>
>
|
>







 







>
>
>
>
>





>












<







 







>



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
...
145
146
147
148
149
150
151
152
153
154
155

DEB_REV=${1-1} # .deb package build/revision number.
PACKAGE_DEBNAME=garradin
THISDIR=${PWD}

DEB_ARCH_NAME=all

PACKAGE_VERSION=`cat ../src/VERSION`

[ ! -f ../src/garradin-${PACKAGE_VERSION}.tar.bz2 ] && (cd ../src; make release)

tar xjvf ../src/garradin-${PACKAGE_VERSION}.tar.bz2 -C /tmp

SRCDIR="/tmp/garradin-${PACKAGE_VERSION}"

test -e ${SRCDIR} || {
    echo "This script must be run from a BUILT copy of the source tree."
    exit 1
}

DEBROOT=$PWD/deb.tmp
test -d ${DEBROOT} && rm -fr ${DEBROOT}
................................................................................

DEBLOCALPREFIX=${DEBROOT}/usr
BINDIR=${DEBLOCALPREFIX}/bin
mkdir -p ${BINDIR}
mkdir -p ${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}
cp ${THISDIR}/garradin ${BINDIR}

mkdir -p "${DEBLOCALPREFIX}/share/menu"
cp ${THISDIR}/garradin.menu "${DEBLOCALPREFIX}/share/menu/garradin"
mkdir -p "${DEBLOCALPREFIX}/share/applications"
cp ${THISDIR}/garradin.desktop "${DEBLOCALPREFIX}/share/applications/"

CODEDIR=${DEBLOCALPREFIX}/share/${PACKAGE_DEBNAME}
mkdir -p ${CODEDIR}
cp -r ${SRCDIR}/* ${CODEDIR}
cp ${THISDIR}/config.debian.php ${CODEDIR}/config.local.php
rm -rf ${CODEDIR}/*.sqlite ${CODEDIR}/cache ${CODEDIR}/www/squelettes
cp ${THISDIR}/garradin.png "${CODEDIR}"

# Cleaning files that will be copied to /usr/share/doc
rm -f ${CODEDIR}/{README,COPYING}

cd $DEBROOT || {
    echo "Debian dest dir [$DEBROOT] not found. :("
    exit 2
}

rm -fr DEBIAN
mkdir DEBIAN


PACKAGE_DEB_VERSION=${PACKAGE_VERSION}-${DEB_REV}
DEBFILE=${THISDIR}/${PACKAGE_DEBNAME}-${PACKAGE_DEB_VERSION}-dev-${DEB_ARCH_NAME}.deb
PACKAGE_TIME=$(/bin/date)

rm -f ${DEBFILE}
echo "Creating .deb package [${DEBFILE}]..."

................................................................................
    dpkg-deb --info ${DEBFILE}
}

cd - >/dev/null
true && {
    echo "Cleaning up..."
    rm -fr ${DEBROOT}
    rm -rf ${SRCDIR}
}

echo "Done :)"

Modified src/Makefile from [1650b4239f] to [054872df85].

27
28
29
30
31
32
33
34
35
36
37
38
39
	ln -s ${PWD} /tmp/garradin-${VERSION}
	tar cjvfh garradin-${VERSION}.tar.bz2 -C /tmp -T /tmp/garradin-${VERSION}-list.txt
	rm -f /tmp/garradin-${VERSION}*

publish: release
	$(eval VERSION=$(shell cat VERSION))
	fossil uv sync
	fossil uv ls | grep '^garradin-.*\.tar\.bz2' | xargs fossil uv rm
	fossil uv add garradin-${VERSION}.tar.bz2
	fossil uv sync

check-dependencies:
	grep -hEo '^use \\?KD2\\\w+|\\KD2\\\w+' -R include/lib/Garradin www | sed -r 's/^use \\?KD2\\|^\\KD2\\//' | sort | uniq







|





27
28
29
30
31
32
33
34
35
36
37
38
39
	ln -s ${PWD} /tmp/garradin-${VERSION}
	tar cjvfh garradin-${VERSION}.tar.bz2 -C /tmp -T /tmp/garradin-${VERSION}-list.txt
	rm -f /tmp/garradin-${VERSION}*

publish: release
	$(eval VERSION=$(shell cat VERSION))
	fossil uv sync
	fossil uv ls | fgrep -v 'garradin-0.8.5' | grep '^garradin-.*\.tar\.bz2' | xargs fossil uv rm
	fossil uv add garradin-${VERSION}.tar.bz2
	fossil uv sync

check-dependencies:
	grep -hEo '^use \\?KD2\\\w+|\\KD2\\\w+' -R include/lib/Garradin www | sed -r 's/^use \\?KD2\\|^\\KD2\\//' | sort | uniq

Modified src/VERSION from [1c75e70a1f] to [ef2e10f968].

1
0.9.1
|
1
0.9.2

Modified src/include/lib/Garradin/Compta/Rapprochement.php from [dbf2a90fad] to [21098b9dae].

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
class Rapprochement
{
    public function getJournal($compte, $debut, $fin, &$solde_initial, &$solde_final, $sauf_deja_rapprochees = false)
    {
        $db = DB::getInstance();

        $query = 'SELECT 
            COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_debit = :compte AND compte_credit IS NOT NULL AND date < :date), 0)
            - COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_credit = :compte AND compte_debit IS NOT NULL  AND date < :date), 0)';

        $solde_initial = $solde = $db->firstColumn($query, [
            'compte'    =>  $compte,
            'date'      =>  $debut,
        ]);

        $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 AS date_rapprochement
            FROM compta_journal AS j
                LEFT JOIN compta_rapprochement AS r ON r.id_operation = j.id
            WHERE (compte_debit = :compte OR compte_credit = :compte)
                AND j.date >= :debut AND j.date <= :fin
                AND compte_debit IS NOT NULL AND compte_credit IS NOT NULL
                ' . ($sauf_deja_rapprochees ? 'AND r.id_operation IS NULL' : '') . '
            ORDER BY date ASC;';

        $result = $db->get($query, [
            'compte'    =>  $compte,
            'debut'     =>  $debut,
            'fin'       =>  $fin,







|
|







 







|







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
class Rapprochement
{
    public function getJournal($compte, $debut, $fin, &$solde_initial, &$solde_final, $sauf_deja_rapprochees = false)
    {
        $db = DB::getInstance();

        $query = 'SELECT 
            COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_debit = :compte AND compte_credit NOT LIKE \'8%\'  AND date < :date), 0)
            - COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_credit = :compte AND compte_debit NOT LIKE \'8%\'  AND date < :date), 0)';

        $solde_initial = $solde = $db->firstColumn($query, [
            'compte'    =>  $compte,
            'date'      =>  $debut,
        ]);

        $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 AS date_rapprochement
            FROM compta_journal AS j
                LEFT JOIN compta_rapprochement AS r ON r.id_operation = j.id
            WHERE (compte_debit = :compte OR compte_credit = :compte)
                AND j.date >= :debut AND j.date <= :fin
                AND compte_debit NOT LIKE \'8%\' AND compte_credit NOT LIKE \'8%\'
                ' . ($sauf_deja_rapprochees ? 'AND r.id_operation IS NULL' : '') . '
            ORDER BY date ASC;';

        $result = $db->get($query, [
            'compte'    =>  $compte,
            'debut'     =>  $debut,
            'fin'       =>  $fin,

Modified src/include/lib/Garradin/Membres.php from [f75ceb8321] to [89209054f9].

346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
        {
            Utils::sendEmail(Utils::EMAIL_CONTEXT_BULK, $config->get('email_asso'), $subject, $message);
        }

        return true;
    }

    public function listAllByCategory($id_categorie)
    {

        return DB::getInstance()->get('SELECT id, email FROM membres WHERE id_categorie = ?;', (int)$id_categorie);
    }

    public function listByCategory($cat, $fields, $page = 1, $order = null, $desc = false)
    {
        $begin = ($page - 1) * self::ITEMS_PER_PAGE;

        $db = DB::getInstance();







|

>
|







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
        {
            Utils::sendEmail(Utils::EMAIL_CONTEXT_BULK, $config->get('email_asso'), $subject, $message);
        }

        return true;
    }

    public function listAllByCategory($id_categorie, $only_with_email = false)
    {
        $where = $only_with_email ? ' AND email IS NOT NULL' : '';
        return DB::getInstance()->get('SELECT id, email FROM membres WHERE id_categorie = ?' . $where, (int)$id_categorie);
    }

    public function listByCategory($cat, $fields, $page = 1, $order = null, $desc = false)
    {
        $begin = ($page - 1) * self::ITEMS_PER_PAGE;

        $db = DB::getInstance();

Modified src/include/lib/Garradin/Membres/Cotisations.php from [07c3d844f4] to [86b67dc8e7].

31
32
33
34
35
36
37






38
39
40
41
42
43
44
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
		if (empty($data['id_cotisation']) 
			|| !$db->firstColumn('SELECT 1 FROM cotisations WHERE id = ?;', (int) $data['id_cotisation']))
		{
			throw new UserException('Cotisation inconnue.');
		}

		$data['id_cotisation'] = (int) $data['id_cotisation'];







		if (empty($data['id_membre']) 
			|| !$db->firstColumn('SELECT 1 FROM membres WHERE id = ?;', (int) $data['id_membre']))
		{
			throw new UserException('Membre inconnu ou invalide.');
		}

................................................................................
			}
		}

		$db->commit();

		Plugin::fireSignal('cotisation.ajout', array_merge(['id' => $id], $data));

		return $id;
	}

	/**
	 * Supprimer un événement de cotisation
	 * @param  integer $id ID de l'événement à supprimer
	 * @return integer true en cas de succès
	 */
................................................................................
	 * (si NULL = cotisation jamais enregistrée, si 1 = cotisation ponctuelle enregistrée, sinon date d'expiration)
	 */
	public function isMemberUpToDate($id, $id_cotisation)
	{
		$db = DB::getInstance();
		return $db->first('SELECT c.*,
			CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\') >= date()
			WHEN c.fin IS NOT NULL THEN (cm.id IS NOT NULL AND date() <= c.fin AND date() >= c.debut)
			WHEN cm.id IS NOT NULL THEN 1 ELSE 0 END AS a_jour,
			CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\')
			WHEN c.fin IS NOT NULL THEN c.fin ELSE 1 END AS expiration
			FROM cotisations AS c 
				LEFT JOIN cotisations_membres AS cm ON cm.id_cotisation = c.id AND cm.id_membre = ?
			WHERE c.id = ? ORDER BY cm.date DESC;',
			(int)$id, (int)$id_cotisation);







>
>
>
>
>
>







 







|







 







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
		if (empty($data['id_cotisation']) 
			|| !$db->firstColumn('SELECT 1 FROM cotisations WHERE id = ?;', (int) $data['id_cotisation']))
		{
			throw new UserException('Cotisation inconnue.');
		}

		$data['id_cotisation'] = (int) $data['id_cotisation'];

		if (!empty($data['numero_membre']))
		{
			$data['id_membre'] = (new Membres)->getIDWithNumero($data['numero_membre']);
			unset($data['numero_membre']);
		}

		if (empty($data['id_membre']) 
			|| !$db->firstColumn('SELECT 1 FROM membres WHERE id = ?;', (int) $data['id_membre']))
		{
			throw new UserException('Membre inconnu ou invalide.');
		}

................................................................................
			}
		}

		$db->commit();

		Plugin::fireSignal('cotisation.ajout', array_merge(['id' => $id], $data));

		return $data['id_membre'];
	}

	/**
	 * Supprimer un événement de cotisation
	 * @param  integer $id ID de l'événement à supprimer
	 * @return integer true en cas de succès
	 */
................................................................................
	 * (si NULL = cotisation jamais enregistrée, si 1 = cotisation ponctuelle enregistrée, sinon date d'expiration)
	 */
	public function isMemberUpToDate($id, $id_cotisation)
	{
		$db = DB::getInstance();
		return $db->first('SELECT c.*,
			CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\') >= date()
			WHEN c.fin IS NOT NULL THEN (cm.id IS NOT NULL)
			WHEN cm.id IS NOT NULL THEN 1 ELSE 0 END AS a_jour,
			CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\')
			WHEN c.fin IS NOT NULL THEN c.fin ELSE 1 END AS expiration
			FROM cotisations AS c 
				LEFT JOIN cotisations_membres AS cm ON cm.id_cotisation = c.id AND cm.id_membre = ?
			WHERE c.id = ? ORDER BY cm.date DESC;',
			(int)$id, (int)$id_cotisation);

Modified src/templates/admin/config/logs.tpl from [bdfa29c9cf] to [c62511fc2c].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
		{foreach from=$main.errors item="error"}
			<h2 class="ruler">{$error.type}: {$error.message} [Code: {$error.errorCode}]</h2>
			{if !empty($error.backtrace)}
				{foreach from=$error.backtrace item=trace}
				<article class="trace">
					{if $trace.function}
						<h4>
							{$trace.function}{if !empty($trace.args)} ({$trace.args|count} arg.){/if}
						{if !empty($trace.args)}
							<table>
							{foreach from=$trace.args key=name item=arg}
								<tr>
									<th>{$name}</th>
									<td>{$arg}</td>
								</tr>







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
		{foreach from=$main.errors item="error"}
			<h2 class="ruler">{$error.type}: {$error.message} [Code: {$error.errorCode}]</h2>
			{if !empty($error.backtrace)}
				{foreach from=$error.backtrace item=trace}
				<article class="trace">
					{if $trace.function}
						<h4>
							{$trace.function}
						{if !empty($trace.args)}
							<table>
							{foreach from=$trace.args key=name item=arg}
								<tr>
									<th>{$name}</th>
									<td>{$arg}</td>
								</tr>

Modified src/www/admin/membres/cotisations/ajout.php from [392b5f9081] to [b2cc2cef01].

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
80
81
82

$cotisations = new Cotisations;
$m_cotisations = new Membres\Cotisations;

$cats = new Compta\Categories;
$banques = new Compta\Comptes_Bancaires;

if (f('add'))
{
    $form->check('add_cotisation', [
        'date'          => 'date_format:Y-m-d|required',
        'id_cotisation' => 'numeric|required|in_table:cotisations,id',
        'id_membre'     => 'numeric|required|in_table:membres,id',
    ]);

    if (!$form->hasErrors())
    {
        try {
            $id_membre = f('id_membre');

            if (!$id_membre && f('numero_membre'))
            {
                $id_membre = (new Membres)->getIDWithNumero(f('numero_membre'));
            }

            $data = [
                'date'          =>  f('date'),
                'id_cotisation' =>  f('id_cotisation'),
                'id_membre'     =>  $id_membre,

                'id_auteur'     =>  $user->id,
            ];

            $compta = [
                'montant'        =>  f('montant'),
                'moyen_paiement' =>  f('moyen_paiement'),
                'numero_cheque'  =>  f('numero_cheque'),
                'banque'         =>  f('banque'),
                'numero_piece'   =>  f('numero_piece'),
                'remarques'      =>  f('remarques'),
                'a_encaisser'    =>  f('a_encaisser'),
            ];

            $m_cotisations->add($data, $compta);

            Utils::redirect(ADMIN_URL . 'membres/cotisations.php?id=' . $id_membre);
        }
        catch (UserException $e)
        {
            $form->addError($e->getMessage());
        }
    }
}

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

$tpl->assign('cotisations', $cotisations->listCurrent());








<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
|
|
|
|
>
|
|

|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
<







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

$cotisations = new Cotisations;
$m_cotisations = new Membres\Cotisations;

$cats = new Compta\Categories;
$banques = new Compta\Comptes_Bancaires;



if (f('add') && $form->check('add_cotisation'))




{


    try {







        $data = [
            'date'          =>  f('date'),
            'id_cotisation' =>  f('id_cotisation'),
            'id_membre'     =>  f('id_membre'),
            'numero_membre' =>  f('numero_membre'),
            'id_auteur'     =>  $user->id,
        ];

        $compta = [
            'montant'        =>  f('montant'),
            'moyen_paiement' =>  f('moyen_paiement'),
            'numero_cheque'  =>  f('numero_cheque'),
            'banque'         =>  f('banque'),
            'numero_piece'   =>  f('numero_piece'),
            'remarques'      =>  f('remarques'),
            'a_encaisser'    =>  f('a_encaisser'),
        ];

        $id_membre = $m_cotisations->add($data, $compta);

        Utils::redirect(ADMIN_URL . 'membres/cotisations.php?id=' . $id_membre);
    }
    catch (UserException $e)
    {
        $form->addError($e->getMessage());

    }
}

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

$tpl->assign('cotisations', $cotisations->listCurrent());

Modified src/www/admin/membres/message_collectif.php from [528d973d74] to [4372383f21].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        'recipients' => 'required|string',
    ]);

    if (preg_match('/^(categorie|recherche)_(\d+)$/', f('recipients'), $match))
    {
        if ($match[1] == 'categorie')
        {
            $recipients = $membres->listAllByCategory($match[2]);
        }
        else
        {
            $recipients = $recherche->search($match[2], 'id, email');
        }

        if (!count($recipients) || !isset($recipients[0]->email))







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        'recipients' => 'required|string',
    ]);

    if (preg_match('/^(categorie|recherche)_(\d+)$/', f('recipients'), $match))
    {
        if ($match[1] == 'categorie')
        {
            $recipients = $membres->listAllByCategory($match[2], true);
        }
        else
        {
            $recipients = $recherche->search($match[2], 'id, email');
        }

        if (!count($recipients) || !isset($recipients[0]->email))

Modified src/www/admin/upgrade.php from [92ea3090d6] to [0233e009d2].

249
250
251
252
253
254
255

256
257
258
259
260
261
262

    if (version_compare($v, '0.9.1', '<'))
    {
        // Mise à jour plan comptable: ajout compte licences fédérales
        $comptes = new Compta\Comptes;
        $comptes->importPlan();


        $db->begin();

        $db->exec('INSERT INTO "compta_categories" VALUES(NULL,-1,\'Licences fédérales\',\'Licences payées pour les adhérents (par exemple fédération sportive etc.)\',\'652\');');

        $db->import(ROOT . '/include/data/0.9.1.sql');

        $db->commit();







>







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

    if (version_compare($v, '0.9.1', '<'))
    {
        // Mise à jour plan comptable: ajout compte licences fédérales
        $comptes = new Compta\Comptes;
        $comptes->importPlan();

        $db->exec('PRAGMA foreign_keys = OFF;');
        $db->begin();

        $db->exec('INSERT INTO "compta_categories" VALUES(NULL,-1,\'Licences fédérales\',\'Licences payées pour les adhérents (par exemple fédération sportive etc.)\',\'652\');');

        $db->import(ROOT . '/include/data/0.9.1.sql');

        $db->commit();