]> git.agnieray.net Git - galette.git/blob - galette/templates/default/pages/contribution_form.html.twig
66da420c4769c21e663fcb8371c6720d61112b92
[galette.git] / galette / templates / default / pages / contribution_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 (mode == 'ajax') ? "ajax.html.twig" : "page.html.twig" %}
22
23 {% block content %}
24 {% if members.list is defined or require_mass %}
25 {% if mode != 'ajax' %}
26 <form action="{% if contribution.id %}{{ url_for("doEditContribution", {"type": type, "id": contribution.id}) }}{% else %}{{ url_for("doAddContribution", {"type": type}) }}{% endif %}" enctype="multipart/form-data" method="post" class="ui form">
27 {% endif %}
28 <div class="ui styled fluid accordion field">
29 <div class="active title">
30 <i class="jsonly displaynone icon dropdown" aria-hidden="true"></i>
31 {% if type == constant('Galette\\Entity\\Contribution::TYPE_FEE') %}
32 {{ _T("Select contributor and membership fee type") }}
33 {% else %}
34 {{ _T("Select contributor and donation type") }}
35 {% endif %}
36 {% if contribution.isTransactionPart() %}
37 <span class="ui teal horizontal label">
38 {{ _T("Transaction related") }}
39 </span>
40 {% endif %}
41 {% if contribution.hasSchedule() %}
42 <span class="ui teal horizontal label">
43 {{ _T("Has scheduled payments") }}
44 </span>
45 {% endif %}
46 </div>
47 <div class="active content">
48 <div class="ui mobile reversed stackable grid">
49 <div class="{% if contribution.isTransactionPart() %}six wide {% endif %}column">
50 {% if not require_mass %}
51 <div class="inline field">
52 <label for="id_adh">{{ _T("Contributor:") }}</label>
53 <div id="id_adh" class="jsonly search-dropdown ui input paginated">
54 <input id="id_adh_input" type="hidden" name="id_adh" value="{{ contribution.member is not null ? contribution.member }}" placeholder="{{ _T("Member ID") }}">
55 <i class="jsonly displaynone dropdown icon" aria-hidden="true"></i>
56 <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>
57 <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>
58 <div class="jsonly displaynone default text">{{ _T("Search for name or ID and pick member") }}</div>
59 <div class="jsonly displaynone menu">
60 {% for k, v in members.list %}
61 <div class="item" data-value="{{ k }}">{{ v }}</div>
62 {% endfor %}
63 </div>
64 </div>
65 </div>
66 {% endif %}
67 <div class="inline field{% if required.id_type_cotis is defined and required.id_type_cotis == 1 %} required{% endif %}">
68 <label for="id_type_cotis">{{ _T("Contribution type:") }}</label>
69 <div id="id_type_cotis" class="ui dropdown selection">
70 {% if contribution.type %}
71 {% set selectedid = contribution.type.id %}
72 {% else %}
73 {% set selectedid = null %}
74 {% endif %}
75 <input id="id_type_cotis_input" type="hidden" name="id_type_cotis" value="{{ selectedid }}"{% if required.id_type_cotis is defined and required.id_type_cotis == 1 %} required="required"{% endif %}>
76 <i class="dropdown icon"></i>
77 <div class="text">{% for key, values in type_cotis_options %}{% if key == selectedid %}{{ values.label }}{% endif %}{% endfor %}</div>
78 <div class="menu">
79 {% for key, values in type_cotis_options %}
80 <div class="item{% if key == selectedid %} active selected{% endif %}" data-value="{{ key }}">{{ values.label }}</div>
81 {% endfor %}
82 </div>
83 </div>
84 </div>
85 </div>
86 {% if contribution.isTransactionPart() or contribution.hasSchedule() %}
87 <div class="ten wide column">
88 {% if contribution.isTransactionPart() %}
89 <div class="ui yellow segment">
90 <div class="ui tiny header">
91 <a
92 href="{{ url_for("editTransaction", {"id": contribution.transaction.id}) }}"
93 class="ui mini icon blue compact button tooltip"
94 >
95 <i class="eye icon tooltip" aria-hidden="true"></i>
96 <span class="ui special popup">{{ _T("View transaction") }}</span>
97 </a>
98 {{ _T("Related transaction information") }}
99 </div>
100 <div class="content">
101 <div class="ui relaxed horizontal list">
102 <div class="item">
103 <div class="content">
104 <div class="header">{{ _T("Date") }}</div>
105 {{ contribution.transaction.date }}
106 </div>
107 </div>
108 <div class="item">
109 <div class="content">
110 <div class="header">{{ _T("Member") }}</div>
111 {{ memberName({'id': contribution.transaction.member}) }}
112 </div>
113 </div>
114 <div class="item">
115 <div class="content">
116 <div class="header">{{ _T("Amount") }}</div>
117 {{ contribution.transaction.amount }}
118 </div>
119 </div>
120 {% if contribution.transaction.getMissingAmount() > 0 %}
121 <div class="item">
122 <div class="content">
123 <div class="header">{{ _T("Not dispatched amount") }}</div>
124 {{ contribution.transaction.getMissingAmount() }}
125 {% if contribution.id != '' %}
126 <a
127 href="{{ url_for("addContribution", {"type": constant('Galette\\Entity\\Contribution::TYPE_FEE')}) }}?trans_id={{ contribution.transaction.id }}"
128 class="ui mini icon green compact button tooltip"
129 title="{{ _T("Create a new fee that will be attached to the current transaction") }}"
130 >
131 <i class="plus tiny icon" aria-hidden="true"></i>
132 <i class="user check icon" aria-hidden="true"></i>
133 <span class="visually-hidden">{{ _T("Create a new fee that will be attached to the current transaction") }}</span>
134 </a>
135 <a
136 href="{{ url_for("addContribution", {"type": constant('Galette\\Entity\\Contribution::TYPE_DONATION')}) }}?trans_id={{ contribution.transaction.id }}"
137 class="ui mini icon green compact button tooltip"
138 title="{{ _T("Create a new donation that will be attached to the current transaction") }}"
139 >
140 <i class="plus tiny icon" aria-hidden="true"></i>
141 <i class="gift icon" aria-hidden="true"></i>
142 <span class="visually-hidden">{{ _T("Create a new donation that will be attached to the current transaction") }}</span>
143 </a>
144 {% endif %}
145 </div>
146 </div>
147 {% endif %}
148 </div>
149 {% if contribution.id == '' %}
150 <div class="inline field">
151 <label>{{ _T("Dispatch type:") }}</label>
152 <i class="circular inverted primary small icon info tooltip" title="{{ _T("Select a contribution type to create for dispatch transaction") }}" aria-hidden="true"></i>
153 <input type="radio" name="contrib_type" id="contrib_type_fee" value="{{ constant('Galette\\Entity\\Contribution::TYPE_FEE') }}"{% if type == constant('Galette\\Entity\\Contribution::TYPE_FEE') %} checked="checked"{% endif %}/> <label for="contrib_type_fee">{{ _T("Membership fee") }}</label>
154 <input type="radio" name="contrib_type" id="contrib_type_donation" value="{{ constant('Galette\\Entity\\Contribution::TYPE_DONATION') }}"{% if type == constant('Galette\\Entity\\Contribution::TYPE_DONATION') %} checked="checked"{% endif %}/> <label for="contrib_type_donation">{{ _T("Donation") }}</label>
155 </div>
156 {% endif %}
157 </div>
158 </div>
159 {% endif %}
160 {% if contribution.hasSchedule() %}
161 {% set scheduled_amount = scheduled.getAllocation(contribution.id) %}
162 <div class="ui yellow segment">
163 <div class="ui tiny header">
164 <a
165 href="#"
166 class="ui mini icon blue compact button tooltip"
167 id="scheduledslist"
168 >
169 <i class="eye icon tooltip" aria-hidden="true"></i>
170 <span class="ui special popup">{{ _T("View scheduled payments") }}</span>
171 </a>
172 {{ _T("Scheduled payments") }}
173 </div>
174 {% if not contribution.isScheduleFullyAllocated() %}
175 <div class="content">
176 <div class="ui relaxed horizontal list">
177 <div class="item">
178 <div class="content">
179 <div class="header">{{ _T("Amount") }}</div>
180 {{ scheduled_amount }}
181 </div>
182 </div>
183 <div class="item">
184 <div class="content">
185 <div class="header">{{ _T("Not dispatched amount") }}</div>
186 {{ contribution.amount - scheduled_amount }}
187 <a
188 href="{{ url_for("addScheduledPayment", {"id_cotis": contribution.id}) }}"
189 class="ui mini icon green compact button tooltip"
190 title="{{ _T("Create a new scheduled payment") }}"
191 >
192 <i class="plus tiny icon" aria-hidden="true"></i>
193 <i class="money bill wave icon" aria-hidden="true"></i>
194 <span class="visually-hidden">{{ _T("Create a new scheduled payment") }}</span>
195 </a>
196 </div>
197 </div>
198 </div>
199 </div>
200 {% endif %}
201 </div>
202 {% endif %}
203 </div>
204 {% endif %}
205 </div>
206 </div>
207 </div>
208
209 <div class="ui styled fluid accordion field">
210 <div class="active title">
211 <i class="jsonly displaynone icon dropdown" aria-hidden="true"></i>
212 {% if type == constant('Galette\\Entity\\Contribution::TYPE_FEE') %}
213 {{ _T("Details of membership fee") }}
214 {% else %}
215 {{ _T("Details of donation") }}
216 {% endif %}
217 </div>
218 <div class="active content field">
219 <div id="contribdetails" class="ui basic fitted segment">
220 <div class="two fields">
221 <div class="field{% if required.montant_cotis is defined and required.montant_cotis == 1 %} required{% endif %}">
222 <label for="montant_cotis">{{ _T("Amount:") }}</label>
223 <input type="text" name="montant_cotis" id="montant_cotis" value="{{ contribution.amount }}" maxlength="10"{% if required.montant_cotis is defined and required.montant_cotis == 1 %} required="required"{% endif %}/>
224 </div>
225 {# payment type #}
226 {% set ptype = contribution.payment_type %}
227 {% if ptype == null %}
228 {% set ptype = preferences.pref_default_paymenttype %}
229 {% endif %}
230 {% include 'components/forms/payment_types.html.twig' with {
231 'current': ptype,
232 'varname': 'type_paiement_cotis',
233 'disabled': contribution.hasSchedule()
234 } %}
235 </div>
236 <div class="{% if type == constant('Galette\\Entity\\Contribution::TYPE_FEE') %}three{% else %}two{% endif %} fields">
237 <div class="field{% if required.date_enreg is defined and required.date_enreg == 1 %} required{% endif %}">
238 <label for="date_enreg">
239 {{ _T("Record date:") }}
240 </label>
241 <div class="ui calendar" id="contribution-rangestart">
242 <div class="ui input left icon">
243 <i class="calendar icon" aria-hidden="true"></i>
244 <input type="text" name="date_enreg" id="date_enreg" value="{{ contribution.date }}" maxlength="10"{% if required.date_enreg is defined and required.date_enreg == 1 %} required="required"{% endif %} placeholder="{{ _T('yyyy-mm-dd format') }}" />
245 </div>
246 </div>
247 </div>
248 <div class="field{% if required.date_debut_cotis is defined and required.date_debut_cotis == 1 %} required{% endif %}">
249 <label for="date_debut_cotis">
250 {% if type == constant('Galette\\Entity\\Contribution::TYPE_FEE') %}
251 {{ _T("Start date of membership:") }}
252 {% else %}
253 {{ _T("Date of contribution:") }}
254 {% endif %}
255 </label>
256 <div class="ui calendar" id="contribution-rangeend">
257 <div class="ui input left icon">
258 <i class="calendar icon" aria-hidden="true"></i>
259 <input type="text" name="date_debut_cotis" id="date_debut_cotis" value="{{ contribution.begin_date }}" maxlength="10"{% if required.date_debut_cotis == 1 %} required="required"{% endif %} placeholder="{{ _T('yyyy-mm-dd format') }}" />
260 </div>
261 </div>
262 </div>
263 {% if type == constant('Galette\\Entity\\Contribution::TYPE_FEE') %}
264 <div class="field{% if required.date_fin_cotis is defined and required.date_fin_cotis == 1 %} required{% endif %}">
265 {% if preferences.pref_membership_ext != "" %}
266 <label for="duree_mois_cotis">{{ _T("Membership extension:") }}</label>
267 <input type="text" name="duree_mois_cotis" id="duree_mois_cotis" value="{{ contribution.duration }}" maxlength="3"{% if required.date_fin_cotis is defined and required.date_fin_cotis == 1 %} required="required"{% endif %}/>
268 <span class="exemple">{{ _T("months") }}</span>
269 {% else %}
270 <label for="date_fin_cotis">{{ _T("End date of membership:") }}</label>
271 <div class="ui calendar" id="membership-rangeend">
272 <div class="ui input left icon">
273 <i class="calendar icon" aria-hidden="true"></i>
274 <input type="text" name="date_fin_cotis" id="date_fin_cotis" value="{{ contribution.end_date }}" maxlength="10"{% if required.date_fin_cotis is defined and required.date_fin_cotis == 1 %} required="required"{% endif %} placeholder="{{ _T('yyyy-mm-dd format') }}" />
275 </div>
276 </div>
277 {% endif %}
278 </div>
279 {% endif %}
280 </div>
281 <div class="field{% if required.info_cotis is defined and required.info_cotis == 1 %} required{% endif %}">
282 <label for="info_cotis">{{ _T("Comments:") }}</label>
283 <textarea name="info_cotis" id="info_cotis" cols="61" rows="6"{% if required.info_cotis is defined and required.info_cotis == 1 %} required="required"{% endif %}>{{ contribution.info }}</textarea>
284 </div>
285 </div>
286 </div>
287 </div>
288
289 {% include 'components/dynamic_fields.html.twig' with {'object': contribution} %}
290
291 {% if not contribution.id and preferences.pref_mail_method != constant('Galette\\Core\\GaletteMail::METHOD_DISABLED') %}
292 {% if not require_mass %}
293 <div class="ui center aligned yellow segment">
294 <div class="inline field">
295 <div class="ui toggle checkbox">
296 <input type="checkbox" name="mail_confirm" id="mail_confirm" value="1"{% if preferences.pref_bool_mailowner or contribution.sendEMail() %} checked="checked"{% endif %}/>
297 <label for="mail_confirm">
298 {{ _T("Notify member") }}
299 </label>
300 <br/>
301 <span class="exemple">
302 {{ _T("Member will receive a notification by email, if he has an address.") }}
303 </span>
304 </div>
305 </div>
306 </div>
307 {% endif %}
308 {% endif %}
309 {% if not require_mass %}
310 <div class="ui basic center aligned segment">
311 <button type="submit" name="valid" class="ui labeled icon primary button action">
312 <i class="save icon" aria-hidden="true"></i> {{ _T("Save") }}
313 </button>
314 <input type="hidden" name="id_cotis" value="{{ contribution.id }}"/>
315 <input type="hidden" name="valid" value="1"/>
316 <input type="hidden" name="trans_id" value="{% if contribution.transaction != NULL %}{{ contribution.transaction.id }}{% endif %}"/>
317 </div>
318 {% endif %}
319 {% if mode != 'ajax' %}
320 {% include "components/forms/csrf.html.twig" %}
321 </form>
322 {% endif %}
323 {% elseif mode != 'ajax' %} {# No members #}
324 <div class="ui warning message" id="warningbox">
325 <h3>{{ _T("No member registered!") }}</h3>
326 <p>
327 {{ _T("Unfortunately, there is no member in your database yet,") }}
328 <br/>
329 <a href="{{ url_for("addMember") }}">{{ _T("please create a member") }}</a>
330 </p>
331 </div>
332 {% endif %}
333 {% endblock %}
334
335 {% block javascripts %}
336 <script type="text/javascript">
337 {% if type == constant('Galette\\Entity\\Contribution::TYPE_FEE') and not contribution.id %}
338 {% include "elements/js/choose_adh.js.twig" with {
339 new_contrib_onchange: true
340 } %}
341 {% else %}
342 {% include "elements/js/choose_adh.js.twig" %}
343 {% endif %}
344
345 $(function() {
346 {% if not contribution.id -%}
347 var _types_amounts = {
348 {%- for key, values in type_cotis_options -%}
349 {%- if values.amount > 0 -%}
350 {{ key }}: {{ values.amount }},
351 {%- endif -%}
352 {%- endfor -%}
353 };
354 $('#id_type_cotis').dropdown({
355 onChange: function(value) {
356 //change to predefined amout if there is one, and if user has not entered data himself
357 if ($('#montant_cotis').data('userset') != true && _types_amounts[value]) {
358 var _amount = _types_amounts[value];
359 alert('Changed to ' + _amount);
360 }
361 }
362 });
363 $('#montant_cotis').on('keyup', function() {
364 //keep trace of user entered data
365 if ($(this).val() == '') {
366 $(this).data('userset', false);
367 } else {
368 $(this).data('userset', true);
369 }
370 });
371 {%- endif %}
372
373 {% if contribution.isTransactionPart() and contribution.transaction.getMissingAmount() %}
374 $('#transaction_related').hide();
375 $('#montant_cotis').on('change', function() {
376 var _amount = {{ contribution.transaction.getMissingAmount() }};
377 var _current = $(this).val();
378 if (_current < _amount) {
379 $('#transaction_related').show();
380 } else if (_current > _amount) {
381 {% include "elements/js/modal.js.twig" with {
382 modal_title_twig: _T("Contribution amount should not be greater than %max")|replace({'%max': contribution.transaction.getMissingAmount()})|e("js"),
383 modal_without_content: true,
384 modal_class: "mini",
385 modal_deny_only: true,
386 modal_cancel_text: _T("Close")|e("js"),
387 modal_classname: "redalert",
388 } %}
389 } else {
390 $('#transaction_related').hide();
391 }
392 });
393 {% endif %}
394
395 {% if contribution.hasSchedule() %}
396 {# Contributions popup #}
397 var _btnuser_mapping = function(){
398 $('#scheduledslist').click(function(){
399 $.ajax({
400 url: '{{ url_for("scheduledPayments") }}',
401 type: "GET",
402 data: {
403 ajax: true,
404 id_cotis: '{{ contribution.id }}'
405 },
406 {% include "elements/js/loader.js.twig" with {
407 selector: '#scheduledslist',
408 loader: 'button'
409 } %},
410 success: function(res){
411 _contribs_dialog(res, '{{ contribution.id }}');
412 },
413 error: function() {
414 {% include "elements/js/modal.js.twig" with {
415 modal_title_twig: _T("An error occurred displaying scheduled payments :(")|e("js"),
416 modal_without_content: true,
417 modal_class: "mini",
418 modal_deny_only: true,
419 modal_cancel_text: _T("Close")|e("js"),
420 modal_classname: "redalert",
421 } %}
422 }
423 });
424 });
425 }
426 _btnuser_mapping();
427
428 var _contribs_dialog = function(res, id_cotis){
429 {% include "elements/js/modal.js.twig" with {
430 modal_title_twig: _T("Scheduled payments")|e("js"),
431 modal_content: "res",
432 modal_class: "scheduledpayments fullscreen",
433 modal_content_class: "scrolling",
434 modal_deny_only: true,
435 modal_cancel_text: _T("Close")|e('js')
436 } %}
437 _contribs_ajax_mapper(res, id_cotis);
438 }
439
440 var _contribs_ajax_mapper = function(res, id_cotis){
441 /*$('.scheduledpayments .filter.icon').remove();
442 $('.scheduledpayments .infoline .button').remove();
443 $('.scheduledpayments .contribution_row input[type=checkbox]').hide();
444
445 //Initialize Fomantic components
446 $('.scheduledpayments .dropdown').dropdown();
447 {% include "elements/js/calendar.js.twig" %}
448
449 //Deactivate contributions list links
450 $('.scheduledpayments tbody a').click(function(){
451 //for links in body (members links), we de nothing
452 return false;
453 });
454
455 //Use JS to send forms
456 $('.scheduledpayments form').on('submit', function(){
457 var _form = $(this);
458 $.ajax({
459 url: _form.attr('action'),
460 type: "POST",
461 data: _form.serialize(),
462 {% include "elements/js/loader.js.twig" with {
463 selector: '.scheduledpayments'
464 } %},
465 success: function(res){
466 $('#main-container').remove();
467 $('.scheduledpayments .content').append(res);
468 _contribs_ajax_mapper(res, max_amount);
469 },
470 error: function() {
471 {% include "elements/js/modal.js.twig" with {
472 modal_title_twig: _T("An error occurred displaying contributions :(")|e("js"),
473 modal_without_content: true,
474 modal_class: "mini",
475 modal_deny_only: true,
476 modal_cancel_text: _T("Close")|e("js"),
477 modal_classname: "redalert",
478 } %}
479 }
480 });
481 return false;
482 });
483
484 _bindDropdownsAutosubmit();*/
485
486 //Bind pagination and ordering links
487 /*$('.scheduledpayments .pagination a, .scheduledpayments thead a').click(function() {
488 $.ajax({
489 url: this.href,
490 type: "GET",
491 data: {
492 ajax: true,
493 max_amount: max_amount
494 },
495 {% include "elements/js/loader.js.twig" with {
496 selector: '.scheduledpayments'
497 } %},
498 success: function(res){
499 $('#main-container').remove();
500 $('.scheduledpayments .content').append(res);
501 _contribs_ajax_mapper(res, max_amount);
502 },
503 error: function() {
504 {% include "elements/js/modal.js.twig" with {
505 modal_title_twig: _T("An error occurred displaying contributions :(")|e("js"),
506 modal_without_content: true,
507 modal_class: "mini",
508 modal_deny_only: true,
509 modal_cancel_text: _T("Close")|e("js"),
510 modal_classname: "redalert",
511 } %}
512 },
513 });
514 return false;
515 });*/
516
517 //Bind reset filters button
518 /*$('#clear_filter').click(function(event) {
519 var _this = $(this);
520 _this.closest('form').submit(function(event) {
521 var _form = $(this);
522 $.ajax({
523 url: _form.attr('action'),
524 type: "POST",
525 data: {
526 clear_filter: true
527 },
528 {% include "elements/js/loader.js.twig" with {
529 selector: '.scheduledpayments'
530 } %},
531 success: function(res){
532 $('#main-container').remove();
533 $('.scheduledpayments .content').append(res);
534 _contribs_ajax_mapper(res, max_amount);
535 },
536 error: function() {
537 {% include "elements/js/modal.js.twig" with {
538 modal_title_twig: _T("An error occurred displaying contributions :(")|e("js"),
539 modal_without_content: true,
540 modal_class: "mini",
541 modal_deny_only: true,
542 modal_cancel_text: _T("Close")|e("js"),
543 modal_classname: "redalert",
544 } %}
545 }
546 });
547 });
548 });*/
549 }
550 {% endif %}
551 });
552 </script>
553 {% endblock %}