Overview
Comment:Implement partial service fee payments
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA1: 80bb46102043d418a3d79102785c026937b57a66
User & Date: bohwaz on 2020-11-08 01:41:44
Other Links: branch diff | manifest | tags
Context
2020-11-08
02:11
Implement list of transactions linked to a service check-in: 54b9d03a1c user: bohwaz tags: dev
01:41
Implement partial service fee payments check-in: 80bb461020 user: bohwaz tags: dev
00:50
Implement list of services per user check-in: 18fdb56468 user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Entities/Services/Service_User.php from [9f8d55fe38] to [4d1fbf7619].

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
	{
		if (null === $this->_fee) {
			$this->_fee = Fees::get($this->id_fee);
		}

		return $this->_fee;
	}


























	static public function saveFromForm(int $user_id, ?array $source = null)
	{
		if (null === $source) {
			$source = $_POST;
		}

		$db = DB::getInstance();
		$db->begin();

		$su = new self;
		$su->date = new \DateTime;
		$su->importForm($source);

		if ($su->fee() && $su->id_user) {
			$su->expected_amount = $su->fee()->getAmountForUser($su->id_user);
		}

		$su->save();

		if ($su->fee()->id_account && !empty($source['amount'])) {
			$transaction = new Transaction;
			$transaction->id_creator = $user_id;
			$transaction->id_year = $su->fee()->id_year;

			$source['type'] = Transaction::TYPE_REVENUE;
			$key = sprintf('account_%d_', $source['type']);
			$source[$key . '0'] = [$su->fee()->id_account => ''];
			$source[$key . '1'] = isset($source['account']) ? $source['account'] : null;

			$source['label'] = 'Règlement activité - ' . $su->service()->label . ' - ' . $su->fee()->label;
			$source['date'] = $su->date->format('d/m/Y');

			$transaction->importFromNewForm($source);
			$transaction->save();
			$transaction->linkToUser($su->id_user, $su->id());
		}

		$db->commit();

		return $su;
	}
}







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


















<
<

<
<
<
|
<
<
<
<
|
<
<

<
|
<
<






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
110
111
112
113
114
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
	{
		if (null === $this->_fee) {
			$this->_fee = Fees::get($this->id_fee);
		}

		return $this->_fee;
	}

	public function addPayment(int $user_id, ?array $source = null)
	{
		if (null === $source) {
			$source = $_POST;
		}

		$transaction = new Transaction;
		$transaction->id_creator = $user_id;
		$transaction->id_year = $this->fee()->id_year;

		$source['type'] = Transaction::TYPE_REVENUE;
		$key = sprintf('account_%d_', $source['type']);
		$source[$key . '0'] = [$this->fee()->id_account => ''];
		$source[$key . '1'] = isset($source['account']) ? $source['account'] : null;

		$source['label'] = 'Règlement activité - ' . $this->service()->label . ' - ' . $this->fee()->label;
		$source['date'] = $this->date->format('d/m/Y');

		$transaction->importFromNewForm($source);
		$transaction->save();
		$transaction->linkToUser($this->id_user, $this->id());

		return $transaction;
	}

	static public function saveFromForm(int $user_id, ?array $source = null)
	{
		if (null === $source) {
			$source = $_POST;
		}

		$db = DB::getInstance();
		$db->begin();

		$su = new self;
		$su->date = new \DateTime;
		$su->importForm($source);

		if ($su->fee() && $su->id_user) {
			$su->expected_amount = $su->fee()->getAmountForUser($su->id_user);
		}



		if ($su->fee()->id_account && !empty($source['amount'])) {



			$su->addPayment($user_id, $source);




		}




		$su->save();



		$db->commit();

		return $su;
	}
}

Modified src/include/lib/Garradin/Services/Services_User.php from [f581a9e609] to [1380a382e3].

21
22
23
24
25
26
27



28
29
30
31
32
33
34

	static public function perUserList(int $user_id): DynamicList
	{
		$columns = [
			'id' => [
				'select' => 'su.id',
			],



			'label' => [
				'select' => 's.label',
				'label' => 'Activité',
			],
			'date' => [
				'label' => 'Date d\'inscription',
				'select' => 'su.date',







>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

	static public function perUserList(int $user_id): DynamicList
	{
		$columns = [
			'id' => [
				'select' => 'su.id',
			],
			'id_account' => [
				'select' => 'sf.id_account',
			],
			'label' => [
				'select' => 's.label',
				'label' => 'Activité',
			],
			'date' => [
				'label' => 'Date d\'inscription',
				'select' => 'su.date',
61
62
63
64
65
66
67
68
69
70
71
			LEFT JOIN acc_transactions_users tu ON tu.id_service_user = su.id
			LEFT JOIN acc_transactions_lines tl ON tl.id_transaction = tu.id_transaction';
		$conditions = sprintf('su.id_user = %d', $user_id);

		$list = new DynamicList($columns, $tables, $conditions);
		$list->orderBy('date', true);
		$list->groupBy('su.id');
		$list->setCount('COUNT(*)');
		return $list;
	}
}







|



64
65
66
67
68
69
70
71
72
73
74
			LEFT JOIN acc_transactions_users tu ON tu.id_service_user = su.id
			LEFT JOIN acc_transactions_lines tl ON tl.id_transaction = tu.id_transaction';
		$conditions = sprintf('su.id_user = %d', $user_id);

		$list = new DynamicList($columns, $tables, $conditions);
		$list->orderBy('date', true);
		$list->groupBy('su.id');
		$list->setCount('COUNT(DISTINCT su.id)');
		return $list;
	}
}

Modified src/templates/acc/transactions/user.tpl from [0752025de3] to [a8bb45e52a].

1
2




3
4
5
6
7
8
9
{include file="admin/_head.tpl" title="Écritures liées à %s"|args:$transaction_user.identite current="acc/accounts"}





{include file="acc/reports/_journal.tpl"}

<h2 class="ruler">Solde des comptes</h2>

<p class="block alert">Cette liste représente le solde des comptes uniquement pour les écritures liées à un membre, et ce sur tous les exercices réunis.</p>

<table class="list">


>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
{include file="admin/_head.tpl" title="Écritures liées à %s"|args:$transaction_user.identite current="acc/accounts"}

<p>
	{linkbutton href="membres/fiche.php?id=%d"|args:$transaction_user.id label="Retour à la fiche membre" shape="user"}
</p>

{include file="acc/reports/_journal.tpl"}

<h2 class="ruler">Solde des comptes</h2>

<p class="block alert">Cette liste représente le solde des comptes uniquement pour les écritures liées à un membre, et ce sur tous les exercices réunis.</p>

<table class="list">

Modified src/templates/admin/membres/fiche.tpl from [7ab0b8783e] to [3ed5055d5c].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    </ul>
</nav>

<dl class="cotisation">
    <dt>Activités et cotisations</dt>
    <dd>
        {if $nb_services == 1}
            Inscrit à <strong>{$nb_services}</strong> activité
        {elseif $nb_activites}
            Inscrit à <strong>{$nb_services}</strong> activités
        {else}
            N'est inscrit à aucune activité
        {/if}
    </dd>
    <dd>
        {linkbutton href="services/user.php?id=%d"|args:$membre.id label="Liste des inscriptions aux activités" shape="menu"}
        {if $session->canAccess('membres', Membres::DROIT_ECRITURE)}
            {linkbutton href="services/save.php?user=%d"|args:$membre.id label="Enregistrer une activité" shape="plus"}
        {/if}







|
|
|

|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    </ul>
</nav>

<dl class="cotisation">
    <dt>Activités et cotisations</dt>
    <dd>
        {if $nb_services == 1}
            <strong>{$nb_services}</strong> inscription à une activité
        {elseif $nb_services}
            <strong>{$nb_services}</strong> inscriptions à des activités
        {else}
            Aucune inscription à des activités
        {/if}
    </dd>
    <dd>
        {linkbutton href="services/user.php?id=%d"|args:$membre.id label="Liste des inscriptions aux activités" shape="menu"}
        {if $session->canAccess('membres', Membres::DROIT_ECRITURE)}
            {linkbutton href="services/save.php?user=%d"|args:$membre.id label="Enregistrer une activité" shape="plus"}
        {/if}

Modified src/templates/services/_nav.tpl from [ea5a7bfe71] to [a7923367e8].

1
2
3
4
5
6
7
8
9
10
11
<nav class="tabs">
	<ul>
		<li{if $current == 'index'} class="current"{/if}><a href="{$admin_url}services/">Activités et cotisations</a></li>
		<li{if $current == 'save'} class="current"{/if}><a href="{$admin_url}services/save.php">Enregistrer une activité</a></li>
		{if $session->canAccess('membres', Membres::DROIT_ADMIN)}
			<li{if $current == 'reminders'} class="current"{/if}><a href="{$admin_url}services/reminders/">Gestion des rappels automatiques</a></li>
		{/if}
	</ul>

	{if isset($current_service)}
	<ul class="sub">



|







1
2
3
4
5
6
7
8
9
10
11
<nav class="tabs">
	<ul>
		<li{if $current == 'index'} class="current"{/if}><a href="{$admin_url}services/">Activités et cotisations</a></li>
		<li{if $current == 'save'} class="current"{/if}><a href="{$admin_url}services/save.php">Inscrire à une activité</a></li>
		{if $session->canAccess('membres', Membres::DROIT_ADMIN)}
			<li{if $current == 'reminders'} class="current"{/if}><a href="{$admin_url}services/reminders/">Gestion des rappels automatiques</a></li>
		{/if}
	</ul>

	{if isset($current_service)}
	<ul class="sub">

Added src/templates/services/payment.tpl version [73745639e2].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
{include file="admin/_head.tpl" title="Enregistrer un règlement" current="membres/services" js=1}

{form_errors}

<form method="post" action="{$self_url}" data-focus="1">

	<fieldset>
		<legend>Enregistrer un règlement</legend>

		<dl>
			<dt>Membre sélectionné</dt>
			<dd><h3>{$user_name}</h3></dd>
			<dt><strong>Inscription</strong></dt>
			{input type="checkbox" name="paid" value="1" default=$su.paid label="Marquer cette inscription comme payée"}
			{input type="money" name="amount" label="Montant réglé par le membre" required=1}
			{input type="list" target="acc/charts/accounts/selector.php?targets=%s"|args:$account_targets name="account" label="Compte de règlement" required=1}
			{input type="text" name="payment_reference" label="Référence de paiement" help="Numéro de chèque, numéro de transaction CB, etc."}
		</dl>
	</fieldset>

	<p class="submit">
		{csrf_field key=$csrf_key}
		<input type="submit" name="save" value="Enregistrer &rarr;" />
	</p>

</form>

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

Modified src/templates/services/save.tpl from [4ea249f9e2] to [475c78c936].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{include file="admin/_head.tpl" title="Enregistrer une activité" current="membres/services" js=1}

{include file="services/_nav.tpl" current="save" fee=null service=null}

{form_errors}

<form method="post" action="{$self_url}" data-focus="1">

	<fieldset>
		<legend>Enregistrer une activité</legend>

{if !$user_id}
		<dl>
			{input type="list" name="user" required=1 label="Sélectionner un membre" default=$selected_user target="membres/selector.php"}
		</dl>
{else}
		<dl>
|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{include file="admin/_head.tpl" title="Enregistrer un règlement" current="membres/services" js=1}

{include file="services/_nav.tpl" current="save" fee=null service=null}

{form_errors}

<form method="post" action="{$self_url}" data-focus="1">

	<fieldset>
		<legend>Inscrire un membre à une activité</legend>

{if !$user_id}
		<dl>
			{input type="list" name="user" required=1 label="Sélectionner un membre" default=$selected_user target="membres/selector.php"}
		</dl>
{else}
		<dl>
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
				</label>
			</dd>
			{/foreach}
		</dl>
		{/foreach}

		<dl>
			{input type="checkbox" name="paid" value="1" default="1" label="Marquer cette activité comme payée"}
			<dd class="help">Décocher cette case pour pouvoir suivre les règlements de personnes qui payent en plusieurs fois. Il sera possible de cocher cette case lorsque le solde aura été réglé.</dd>
		</dl>
	</fieldset>

	<fieldset class="accounting">
		<legend>Enregistrement en comptabilité</legend>

		<dl>
			{input type="money" name="amount" label="Montant réglé par le membre" required=1 help="En cas de règlement en plusieurs fois il sera possible d'ajouter des règlements via la page de suivi des activités de ce membre."}
			{input type="list" target="acc/charts/accounts/selector.php?targets=%s"|args:$account_targets name="account" label="Compte de règlement" required=1}
			{input type="text" name="payment_reference" label="Référence de paiement" help="Numéro de chèque, numéro de transaction CB, etc."}
		</dl>
{/if}
	</fieldset>

	<p class="submit">







|








|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
				</label>
			</dd>
			{/foreach}
		</dl>
		{/foreach}

		<dl>
			{input type="checkbox" name="paid" value="1" default="1" label="Marquer cette inscription comme payée"}
			<dd class="help">Décocher cette case pour pouvoir suivre les règlements de personnes qui payent en plusieurs fois. Il sera possible de cocher cette case lorsque le solde aura été réglé.</dd>
		</dl>
	</fieldset>

	<fieldset class="accounting">
		<legend>Enregistrement en comptabilité</legend>

		<dl>
			{input type="money" name="amount" label="Montant réglé par le membre" fake_required=1 help="En cas de règlement en plusieurs fois il sera possible d'ajouter des règlements via la page de suivi des activités de ce membre."}
			{input type="list" target="acc/charts/accounts/selector.php?targets=%s"|args:$account_targets name="account" label="Compte de règlement" required=1}
			{input type="text" name="payment_reference" label="Référence de paiement" help="Numéro de chèque, numéro de transaction CB, etc."}
		</dl>
{/if}
	</fieldset>

	<p class="submit">

Modified src/templates/services/user.tpl from [70da61d01d] to [87355b82f5].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{include file="admin/_head.tpl" title="%s — Liste des activités"|args:$user.identite current="membres/services"}

<p>
	{linkbutton href="membres/fiche.php?id=%d"|args:$user.id label="Retour à la fiche membre" shape="user"}
	{linkbutton href="services/save.php?user=%d"|args:$user.id label="Enregistrer une activité" shape="plus"}
</p>

{form_errors}

<dl class="cotisation">
	<dt>Nombre d'activités inscrites pour ce membre</dt>
	<dd>
		{$list->count()}
	</dd>
</dl>

{include file="common/dynamic_list_head.tpl"}











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{include file="admin/_head.tpl" title="%s — Liste des activités"|args:$user.identite current="membres/services"}

<p>
	{linkbutton href="membres/fiche.php?id=%d"|args:$user.id label="Retour à la fiche membre" shape="user"}
	{linkbutton href="services/save.php?user=%d"|args:$user.id label="Enregistrer une activité" shape="plus"}
</p>

{form_errors}

<dl class="cotisation">
	<dt>Nombre d'inscriptions pour ce membre</dt>
	<dd>
		{$list->count()}
	</dd>
</dl>

{include file="common/dynamic_list_head.tpl"}

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
				{if $session->canAccess('membres', Membres::DROIT_ECRITURE)}
					{if $row.paid}
						{linkbutton shape="reset" label="Marquer comme non payé" href="services/user.php?id=%d&su_id=%d&paid=0"|args:$user.id,$row.id}
					{else}
						{linkbutton shape="check" label="Marquer comme payé" href="services/user.php?id=%d&su_id=%d&paid=1"|args:$user.id,$row.id}
					{/if}
				{/if}
				{if $session->canAccess('compta', Membres::DROIT_ACCES)}
					{linkbutton shape="menu" label="Liste des écritures" href="acc/transactions/service_user.php?id=%d"|args:$row.id}
				{/if}
				{if $session->canAccess('compta', Membres::DROIT_ECRITURE)}
					{linkbutton shape="plus" label="Nouveau règlement" href="services/payment.php?id=%d"|args:$row.id}
				{/if}
			</td>
		</tr>
	{/foreach}

	</tbody>
</table>

{pagination url=$list->paginationURL() page=$list.page bypage=$list.per_page total=$list->count()}


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







|


|













37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
				{if $session->canAccess('membres', Membres::DROIT_ECRITURE)}
					{if $row.paid}
						{linkbutton shape="reset" label="Marquer comme non payé" href="services/user.php?id=%d&su_id=%d&paid=0"|args:$user.id,$row.id}
					{else}
						{linkbutton shape="check" label="Marquer comme payé" href="services/user.php?id=%d&su_id=%d&paid=1"|args:$user.id,$row.id}
					{/if}
				{/if}
				{if $session->canAccess('compta', Membres::DROIT_ACCES) && $row.id_account}
					{linkbutton shape="menu" label="Liste des écritures" href="acc/transactions/service_user.php?id=%d"|args:$row.id}
				{/if}
				{if $session->canAccess('compta', Membres::DROIT_ECRITURE) && $row.id_account}
					{linkbutton shape="plus" label="Nouveau règlement" href="services/payment.php?id=%d"|args:$row.id}
				{/if}
			</td>
		</tr>
	{/foreach}

	</tbody>
</table>

{pagination url=$list->paginationURL() page=$list.page bypage=$list.per_page total=$list->count()}


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

Added src/www/admin/services/payment.php version [a8ad0d0fc0].













































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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;

use Garradin\Services\Services_User;
use Garradin\Entities\Accounting\Account;
use Garradin\Entities\Accounting\Transaction;

require_once __DIR__ . '/_inc.php';

$session->requireAccess('membres', Membres::DROIT_ECRITURE);

$su = Services_User::get((int)qg('id'));

if (!$su) {
	throw new UserException("Cette inscription n'existe pas");
}

$user_name = (new Membres)->getNom($su->id_user);

$csrf_key = 'service_pay';

$form->runIf('save', function () use ($su, $session) {
	$su->addPayment($session->getUser()->id);

	if ($su->paid != (bool) f('paid')) {
		$su->paid = (bool) f('paid');
		$su->save();
	}

	Utils::redirect(ADMIN_URL . 'services/user.php?id=' . $su->id_user);
}, $csrf_key);

$types_details = Transaction::getTypesDetails();
$account_targets = $types_details[Transaction::TYPE_REVENUE]->accounts[1]->targets_string;

$tpl->assign(compact('csrf_key', 'account_targets', 'user_name', 'su'));

$tpl->display('services/payment.tpl');