]> git.agnieray.net Git - galette.git/blob - galette/templates/default/pages/transaction_form.html.twig
4759c76ebef1acce136b38c5c3751ae515a0eee0
[galette.git] / galette / templates / default / pages / transaction_form.html.twig
1 {#
2 /**
3 * Copyright © 2003-2024 The Galette Team
4 *
5 * This file is part of Galette (https://galette.eu).
6 *
7 * Galette is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Galette is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
19 */
20 #}
21 {% extends "page.html.twig" %}
22
23 {% block content %}
24 {% if members.list is defined %}
25 <form action="{% if transaction.id %}{{ url_for("editTransaction", {"id": transaction.id}) }}{% else %}{{ url_for("addTransaction") }}{% endif %}" enctype="multipart/form-data" method="post" class="ui form">
26 <div class="ui styled fluid accordion field">
27 <div class="active title">
28 <i class="jsonly displaynone icon dropdown" aria-hidden="true"></i>
29 {{ _T("Transaction details") }}
30 </div>
31 <div class="active content">
32 <div class="ui mobile reversed stackable grid">
33 <div class="{% if transaction.id %}five wide {% endif %}column">
34 <div class="field inline{% if required.trans_desc is defined and required.trans_desc == 1 %} required{% endif %}">
35 <label for="trans_desc">{{ _T("Description:") }}</label>
36 <input type="text" name="trans_desc" id="trans_desc" value="{{ transaction.description }}" maxlength="150" size="30"{% if required.trans_desc is defined and required.trans_desc == 1 %} required="required"{% endif %}/>
37 </div>
38 <div class="field inline{% if required.id_adh is defined and required.id_adh == 1 %} required{% endif %}">
39 <label for="id_adh" >{{ _T("Originator:") }}</label>
40 <div id="id_adh" class="jsonly search-dropdown ui input paginated"{% if required.id_adh is defined and required.id_adh == 1 %} required="required"{% endif %}>
41 <input id="id_adh_input" type="text" name="id_adh" value="{{ transaction.member is not null ? transaction.member }}" placeholder="{{ _T("Member ID") }}">
42 <i class="jsonly displaynone dropdown icon" aria-hidden="true"></i>
43 <span class="ui mini compact icon disabled button prev-results"><i class="jsonly displaynone chevron circle left icon disabled button tooltip" title="{{ _T("Load previous members...") }}" aria-hidden="true"></i></span>
44 <span class="ui mini compact icon disabled button next-results"><i class="jsonly displaynone chevron circle right icon disabled button tooltip" title="{{ _T("Load following members...") }}" aria-hidden="true"></i></span>
45 <div class="jsonly displaynone default text">{% if not transaction.member %}{{ _T("Search for name or ID and pick member") }}{% endif %}</div>
46 <div class="jsonly displaynone menu">
47 {% for k, v in members.list %}
48 <div class="item" data-value="{{ k }}">{{ v }}</div>
49 {% endfor %}
50 </div>
51 </div>
52 </div>
53 <div class="field inline{% if required.trans_date is defined and required.trans_date == 1 %} required{% endif %}">
54 <label for="trans_date">{{ _T("Date:") }}</label>
55 <div class="ui calendar" id="transaction-rangestart">
56 <div class="ui input left icon">
57 <i class="calendar icon" aria-hidden="true"></i>
58 <input type="text" class="date-pick" name="trans_date" id="trans_date" value="{{ transaction.date }}" maxlength="10"{% if required.trans_date is defined and required.trans_date == 1 %} required="required"{% endif %} placeholder="{{ _T('yyyy-mm-dd format') }}" />
59 </div>
60 </div>
61 </div>
62 <div class="field inline{% if required.trans_amount is defined and required.trans_amount == 1 %} required{% endif %}">
63 <label for="trans_amount">{{ _T("Amount:") }}</label>
64 <input type="text" name="trans_amount" id="trans_amount" value="{{ transaction.amount }}" maxlength="10"{% if required.trans_amount is defined and required.trans_amount == 1 %} required="required"{% endif %}/>
65 </div>
66 <div class="field inline{% if required.trans_payment_type is defined and required.trans_payment_type == 1 %} required{% endif %}">
67 {# payment type #}
68 {% set ptype = transaction.payment_type %}
69 {% include 'components/forms/payment_types.html.twig' with {
70 'current': ptype,
71 'varname': 'type_paiement_trans',
72 'show_inline': true,
73 'empty': {
74 'label': _T("None"),
75 'value': '0'
76 }
77 } %}
78 </div>
79 {% if transaction.id == null %}
80 <div class="field inline">
81 <label class="inline" title="{{ _T("Select a contribution type to create for dispatch transaction") }}">{{ _T("Dispatch type:") }}</label>
82 <i class="circular inverted primary small icon info tooltip" title="{{ _T("Select a contribution type to create for dispatch transaction") }}" aria-hidden="true"></i>
83 <input type="radio" name="contrib_type" id="contrib_type_fee" value="{{ constant('Galette\\Entity\\Contribution::TYPE_FEE') }}"/> <label for="contrib_type_fee">{{ _T("Membership fee") }}</label>
84 <input type="radio" name="contrib_type" id="contrib_type_donation" value="{{ constant('Galette\\Entity\\Contribution::TYPE_DONATION') }}"/> <label for="contrib_type_donation">{{ _T("Donation") }}</label>
85 </div>
86 {% endif %}
87 </div>
88 {% if transaction.id %}
89 <div class="eleven wide column">
90 <div class="ui tiny header">{{ _T("Attached contributions") }}</div>
91 <table class="listing ui very compact small celled yellow table">
92 <thead>
93 <tr>
94 <th class="id_row">#</th>
95 <th class="left date_row">{{ _T("Date") }}</th>
96 <th class="left date_row">{{ _T("Begin") }}</th>
97 <th class="left date_row">{{ _T("End") }}</th>
98 <th class="left">{{ _T("Duration") }}</th>
99 {% if login.isAdmin() or login.isStaff() %}
100 <th class="left">{{ _T("Member") }}</th>
101 {% endif %}
102 <th class="left">{{ _T("Type") }}</th>
103 <th class="left">{{ _T("Amount") }}</th>
104 {% if login.isAdmin() or login.isStaff() %}
105 <th class="actions_row">{{ _T("Actions") }}</th>
106 {% endif %}
107 </tr>
108 </thead>
109 <tfoot>
110 <tr>
111 <th class="right bgfree" colspan="{% if login.isAdmin() or login.isStaff() %}7{% else %}5{% endif %}">{{ _T("Dispatched amount:") }}</th>
112 <th class="right bgfree">{{ transaction.getDispatchedAmount() }}</th>
113 <td></td>
114 </tr>
115 <tr>
116 <th class="right bgfree" colspan="{% if login.isAdmin() or login.isStaff() %}7{% else %}5{% endif %}">{{ _T("Not dispatched amount:") }}</th>
117 <th class="right bgfree">{{ transaction.getMissingAmount() }}</th>
118 <td></td>
119 </tr>
120 {% if transaction.getMissingAmount() > 0 %}
121 <tr>
122 <th colspan="{% if login.isAdmin() or login.isStaff() %}9{% else %}7{% endif %}">
123 <div class="ui basic fitted right aligned segment">
124 <a
125 href="{{ url_for("addContribution", {"type": constant('Galette\\Entity\\Contribution::TYPE_FEE')}) }}?trans_id={{ transaction.id }}"
126 class="ui icon green compact button tooltip"
127 title="{{ _T("Create a new fee that will be attached to the current transaction") }}"
128 >
129 <i class="plus tiny icon" aria-hidden="true"></i>
130 <i class="user check icon" aria-hidden="true"></i>
131 <span class="visually-hidden">{{ _T("Create a new fee that will be attached to the current transaction") }}</span>
132 </a>
133 <a
134 href="{{ url_for("addContribution", {"type": constant('Galette\\Entity\\Contribution::TYPE_DONATION')}) }}?trans_id={{ transaction.id }}"
135 class="ui icon green compact button tooltip"
136 title="{{ _T("Create a new donation that will be attached to the current transaction") }}"
137 >
138 <i class="plus tiny icon" aria-hidden="true"></i>
139 <i class="gift icon" aria-hidden="true"></i>
140 <span class="visually-hidden">{{ _T("Create a new donation that will be attached to the current transaction") }}</span>
141 </a>
142 <a
143 href="#"
144 class="ui icon blue compact button tooltip"
145 title="{{ _T("Select an existing contribution in the database, and attach it to the current transaction") }}"
146 id="contribslist"
147 >
148 <i class="receipt icon" aria-hidden="true"></i>
149 <span class="visually-hidden">{{ _T("Select an existing contribution in the database, and attach it to the current transaction") }}</span>
150 </a>
151 </div>
152 </th>
153 </tr>
154 {% endif %}
155 </tfoot>
156 <tbody>
157 {% for ordre, contrib in contribs %}
158 {% set mid = contrib.member %}
159 <tr class="{{ contrib.getRowClass() }}">
160 <td class="center">
161 {{ ordre + 1 }}
162 </td>
163 <td class="center">{{ contrib.date }}</td>
164 <td class="center">{{ contrib.begin_date }}</td>
165 <td class="center">{{ contrib.end_date }}</td>
166 <td>{{ contrib.duration }}</td>
167 {% if login.isAdmin() or login.isStaff() %}
168 <td>{{ memberName({'id': mid}) }}</td>
169 {% endif %}
170 <td>{{ contrib.type.libelle }}</td>
171 <td class="right">{{ contrib.amount }}</td>
172 {% if login.isAdmin() or login.isStaff() %}
173 <td class="actions_row">
174 <a
175 href="{{ url_for("detach_contribution", {"id": transaction.id, "cid": contrib.id}) }}"
176 class="delete"
177 >
178 <i class="ui red trash icon tooltip" aria-hidden="true"></i>
179 <span class="ui special popup">{{ _T("Detach contribution from this transaction") }}</span>
180 </a>
181 </td>
182 {% endif %}
183 </tr>
184 {% else %}
185 <tr><td colspan="{% if login.isAdmin() or login.isStaff() %}9{% else %}7{% endif %}" class="emptylist">{{ _T("no contribution") }}</td></tr>
186 {% endfor %}
187 </tbody>
188 </table>
189 </div>
190 {% endif %}
191 </div>
192 </div>
193 </div>
194
195 {% include "components/dynamic_fields.html.twig" with {'object': transaction} %}
196
197 <div class="ui basic center aligned segment">
198 <button type="submit" name="valid" class="ui labeled icon primary button action">
199 <i class="save icon" aria-hidden="true"></i> {{ _T("Save") }}
200 </button>
201 <input type="hidden" name="trans_id" value="{{ transaction.id }}"/>
202 <input type="hidden" name="valid" value="1"/>
203 {% include "components/forms/csrf.html.twig" %}
204 </div>
205 </form>
206 {% else %} {# No members #}
207 <div class="ui warning message" id="warningbox">
208 <h3>{{ _T("No member registered!") }}</h3>
209 <p>
210 {{ _T("Unfortunately, there is no member in your database yet,") }}
211 <br/>
212 <a href="{{ url_for("addMember") }}">{{ _T("please create a member") }}</a>
213 </p>
214 </div>
215 {% endif %}
216 {% endblock %}
217
218 {% block javascripts %}
219 <script type="text/javascript">
220 {% include "elements/js/choose_adh.js.twig" %}
221 document.getElementById('id_adh_input').type = 'hidden';
222
223 $(function(){
224 {% if transaction.id %}
225 {# Contributions popup #}
226 var _btnuser_mapping = function(){
227 $('#contribslist').click(function(){
228 $.ajax({
229 url: '{{ url_for("contributions", {"type": "contributions"}) }}',
230 type: "GET",
231 data: {
232 ajax: true,
233 max_amount: '{{ transaction.getMissingAmount() }}'
234 },
235 {% include "elements/js/loader.js.twig" with {
236 selector: '#contribslist',
237 loader: 'button'
238 } %},
239 success: function(res){
240 _contribs_dialog(res, '{{ transaction.getMissingAmount() }}');
241 },
242 error: function() {
243 {% include "elements/js/modal.js.twig" with {
244 modal_title_twig: _T("An error occurred displaying members interface :(")|e("js"),
245 modal_without_content: true,
246 modal_class: "mini",
247 modal_deny_only: true,
248 modal_cancel_text: _T("Close")|e("js"),
249 modal_classname: "redalert",
250 } %}
251 }
252 });
253 });
254 }
255 _btnuser_mapping();
256
257 var _contribs_dialog = function(res, max_amount){
258 {% include "elements/js/modal.js.twig" with {
259 modal_title_twig: _T("Contributions selection")|e("js"),
260 modal_content: "res",
261 modal_class: "contributions-selection fullscreen",
262 modal_content_class: "scrolling",
263 modal_deny_only: true,
264 modal_cancel_text: _T("Close")|e('js')
265 } %}
266 _contribs_ajax_mapper(res, max_amount);
267 }
268
269 var _contribs_ajax_mapper = function(res, max_amount){
270 $('.contributions-selection .filter.icon').remove();
271 $('.contributions-selection .infoline .button').remove();
272 $('.contributions-selection .contribution_row input[type=checkbox]').hide();
273
274 //Initialize Fomantic components
275 $('.contributions-selection .dropdown').dropdown();
276 {% include "elements/js/calendar.js.twig" %}
277
278 //Deactivate contributions list links
279 $('.contributions-selection tbody a').click(function(){
280 //for links in body (members links), we de nothing
281 return false;
282 });
283
284 //Use JS to send forms
285 $('.contributions-selection form').on('submit', function(){
286 var _form = $(this);
287 $.ajax({
288 url: _form.attr('action'),
289 type: "POST",
290 data: _form.serialize(),
291 {% include "elements/js/loader.js.twig" with {
292 selector: '.contributions-selection'
293 } %},
294 success: function(res){
295 $('#main-container').remove();
296 $('.contributions-selection .content').append(res);
297 _contribs_ajax_mapper(res, max_amount);
298 },
299 error: function() {
300 {% include "elements/js/modal.js.twig" with {
301 modal_title_twig: _T("An error occurred displaying contributions :(")|e("js"),
302 modal_without_content: true,
303 modal_class: "mini",
304 modal_deny_only: true,
305 modal_cancel_text: _T("Close")|e("js"),
306 modal_classname: "redalert",
307 } %}
308 }
309 });
310 return false;
311 });
312
313 _bindDropdownsAutosubmit();
314
315 //Bind pagination and ordering links
316 $('.contributions-selection .pagination a, .contributions-selection thead a').click(function() {
317 $.ajax({
318 url: this.href,
319 type: "GET",
320 data: {
321 ajax: true,
322 max_amount: max_amount
323 },
324 {% include "elements/js/loader.js.twig" with {
325 selector: '.contributions-selection'
326 } %},
327 success: function(res){
328 $('#main-container').remove();
329 $('.contributions-selection .content').append(res);
330 _contribs_ajax_mapper(res, max_amount);
331 },
332 error: function() {
333 {% include "elements/js/modal.js.twig" with {
334 modal_title_twig: _T("An error occurred displaying contributions :(")|e("js"),
335 modal_without_content: true,
336 modal_class: "mini",
337 modal_deny_only: true,
338 modal_cancel_text: _T("Close")|e("js"),
339 modal_classname: "redalert",
340 } %}
341 },
342 });
343 return false;
344 });
345
346 //Bind reset filters button
347 $('#clear_filter').click(function(event) {
348 var _this = $(this);
349 _this.closest('form').submit(function(event) {
350 var _form = $(this);
351 $.ajax({
352 url: _form.attr('action'),
353 type: "POST",
354 data: {
355 clear_filter: true
356 },
357 {% include "elements/js/loader.js.twig" with {
358 selector: '.contributions-selection'
359 } %},
360 success: function(res){
361 $('#main-container').remove();
362 $('.contributions-selection .content').append(res);
363 _contribs_ajax_mapper(res, max_amount);
364 },
365 error: function() {
366 {% include "elements/js/modal.js.twig" with {
367 modal_title_twig: _T("An error occurred displaying contributions :(")|e("js"),
368 modal_without_content: true,
369 modal_class: "mini",
370 modal_deny_only: true,
371 modal_cancel_text: _T("Close")|e("js"),
372 modal_classname: "redalert",
373 } %}
374 }
375 });
376 });
377 });
378
379 //Select a row
380 $('.contributions-selection .contribution_row').click(function(){
381 $('.contributions-selection').modal('hide');
382 var _cid = $(this).find('input[name="entries_sel[]"]').val();
383 window.location.href = '{{ url_for("attach_contribution", {"id": transaction.id, "cid": "%cid"}) }}'.replace(/%cid/, _cid);
384 }).css('cursor', 'pointer').attr('title', '{{ _T("Click on a contribution row to attach it to the current transaction")|e('js') }}');
385 }
386 {% endif %}
387 });
388 </script>
389 {% endblock %}