1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-24 19:20:29 +02:00

Merge remote-tracking branch 'origin/master' into activity

# Conflicts:
#	note_kfet/urls.py
#	templates/base.html
This commit is contained in:
Yohann D'ANELLO
2020-03-27 00:32:22 +01:00
482 changed files with 89737 additions and 1166 deletions

View File

@ -1,4 +1,4 @@
{% load static i18n pretty_money static %}
{% load static i18n pretty_money static getenv perms %}
{% comment %}
SPDX-License-Identifier: GPL-3.0-or-later
{% endcomment %}
@ -46,12 +46,20 @@ SPDX-License-Identifier: GPL-3.0-or-later
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.2.0/turbolinks.js"
crossorigin="anonymous"></script>
<script src="/static/js/base.js"></script>
{# Si un formulaire requiert des données supplémentaires (notamment JS), les données sont chargées #}
{% if form.media %}
{{ form.media }}
{% endif %}
<style>
.validate:hover {
cursor: pointer;
text-decoration: underline;
}
</style>
{% block extracss %}{% endblock %}
</head>
<body class="d-flex w-100 h-100 flex-column">
@ -66,24 +74,36 @@ SPDX-License-Identifier: GPL-3.0-or-later
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="{% url 'note:consos' %}"><i class="fa fa-coffee"></i> Consos</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="{% url 'member:club_list' %}"><i class="fa fa-users"></i> Clubs</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="{% url 'activity:activity_list' %}"><i class="fa fa-calendar"></i> Activités</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="{% url 'note:template_list' %}"><i class="fa fa-coffee"></i> Bouton</a>
</li>
{% if "note.transactiontemplate"|not_empty_model_list %}
<li class="nav-item active">
<a class="nav-link" href="{% url 'note:consos' %}"><i class="fa fa-coffee"></i> {% trans 'Consumptions' %}</a>
</li>
{% endif %}
<li class="nav-item active">
<a class="nav-link" href="{% url 'note:transfer' %}"><i class="fa fa-exchange"></i>{% trans 'Transfer' %} </a>
</li>
{% if "member.club"|not_empty_model_list %}
<li class="nav-item active">
<a class="nav-link" href="{% url 'member:club_list' %}"><i class="fa fa-users"></i> {% trans 'Clubs' %}</a>
</li>
{% endif %}
{% if "activity.activity"|not_empty_model_list %}
<li class="nav-item active">
<a class="nav-link" href="{% url 'activity:activity_list' %}"><i class="fa fa-calendar"></i> {% trans 'Activities' %}</a>
</li>
{% endif %}
{% if "treasury.invoice"|not_empty_model_change_list %}
<li class="nav-item active">
<a class="nav-link" href="{% url 'treasury:invoice_list' %}"><i class="fa fa-money"></i>{% trans 'Treasury' %} </a>
</li>
{% endif %}
</ul>
<ul class="navbar-nav ml-auto">
{% if user.is_authenticated %}
<li class="dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-user"></i> {{ user.username }} ({{ user.note.balance | pretty_money }})
<i class="fa fa-user"></i>
<span id="user_balance">{{ user.username }} ({{ user.note.balance | pretty_money }})</span>
</a>
<div class="dropdown-menu dropdown-menu-right"
aria-labelledby="navbarDropdownMenuLink">
@ -112,6 +132,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
</nav>
<div class="container-fluid my-3" style="max-width: 1600px;">
{% block contenttitle %}<h1>{{ title }}</h1>{% endblock %}
<div id="messages"></div>
{% block content %}
<p>Default content...</p>
{% endblock content %}
@ -125,7 +146,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
class="form-inline">
<span class="text-muted mr-1">
NoteKfet2020 &mdash;
<a href="mailto:tresorie.bde@lists.crans.org"
<a href="mailto:{{ "CONTACT_EMAIL" | getenv }}"
class="text-muted">Nous contacter</a> &mdash;
</span>
{% csrf_token %}
@ -155,6 +176,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
</div>
</footer>
<script>
CSRF_TOKEN = "{{ csrf_token }}";
</script>
{% block extrajavascript %}
{% endblock extrajavascript %}
</body>

View File

@ -0,0 +1,99 @@
{% load i18n %}{% load static %}{% get_current_language as LANGUAGE_CODE %}<!DOCTYPE html>
<html{% if LANGUAGE_CODE %} lang="{{LANGUAGE_CODE}}"{% endif %}>
<head>
<meta charset="utf-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" /><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% trans "Central Authentication Service" %}{% endblock %}</title>
<link href="{{settings.CAS_COMPONENT_URLS.bootstrap3_css}}" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="{{settings.CAS_COMPONENT_URLS.html5shiv}}"></script>
<script src="{{settings.CAS_COMPONENT_URLS.respond}}"></script>
<![endif]-->
{% if settings.CAS_FAVICON_URL %}<link rel="shortcut icon" href="{{settings.CAS_FAVICON_URL}}" />{% endif %}
<link href="{% static "cas_server/styles.css" %}" rel="stylesheet">
</head>
<body>
<div id="wrap">
<div class="container">
{% if auto_submit %}<noscript>{% endif %}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<h1 id="app-name">
{% if settings.CAS_LOGO_URL %}<img src="{{settings.CAS_LOGO_URL}}" alt="cas-logo" />{% endif %}
Authentification Note Kfet 2020</h1>
</div>
</div>
{% if auto_submit %}</noscript>{% endif %}
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-2 col-xs-12"></div>
<div class="col-lg-6 col-md-6 col-sm-8 col-xs-12">
{% if auto_submit %}<noscript>{% endif %}
{% for msg in CAS_INFO_RENDER %}
<div class="alert alert-{{msg.type}}{% if msg.discardable %} alert-dismissable{% endif %}">
{% if msg.discardable %}<button type="button" class="close" data-dismiss="alert" aria-hidden="true" id="info-{{msg.name}}">&#215;</button>{% endif %}
<p>{{msg.message}}</p>
</div>
{% endfor %}
{% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
<div class="alert alert-info alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true" id="alert-version">&#215;</button>
<p>{% blocktrans %}A new version of the application is available. This instance runs {{VERSION}} and the last version is {{LAST_VERSION}}. Please consider upgrading.{% endblocktrans %}</p>
</div>
{% endif %}
{% block ante_messages %}{% endblock %}
{% for message in messages %}
<div {% spaceless %}
{% if message.level == message_levels.DEBUG %}
class="alert alert-warning"
{% elif message.level == message_levels.INFO %}
class="alert alert-info"
{% elif message.level == message_levels.SUCCESS %}
class="alert alert-success"
{% elif message.level == message_levels.WARNING %}
class="alert alert-warning"
{% else %}
class="alert alert-danger"
{% endif %}
{% endspaceless %}>
<p>{{message}}</p>
</div>
{% endfor %}
{% if auto_submit %}</noscript>{% endif %}
{% block content %}{% endblock %}
</div>
<div class="col-lg-3 col-md-3 col-sm-2 col-xs-0"></div>
</div>
</div> <!-- /container -->
</div>
<div style="clear: both;"></div>
{% if settings.CAS_SHOW_POWERED %}
<div id="footer">
<p><a class="text-muted" href="https://pypi.org/project/django-cas-server/">django-cas-server powered</a></p>
</div>
{% endif %}
<script src="{{settings.CAS_COMPONENT_URLS.jquery}}"></script>
<script src="{{settings.CAS_COMPONENT_URLS.bootstrap3_js}}"></script>
<script src="{% static "cas_server/functions.js" %}"></script>
<script type="text/javascript">
{% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
discard_and_remember("#alert-version", "cas-alert-version", "{{LAST_VERSION}}");
{% endif %}
{% for msg in CAS_INFO_RENDER %}
{% if msg.discardable %}
discard_and_remember("#info-{{msg.name}}", "cas-info-{{msg.name}}", "{{msg.hash}}");
{% endif %}
{% endfor %}
{% block javascript_inline %}{% endblock %}
</script>
{% block javascript %}{% endblock %}
</body>
</html>
<!--
Powered by django-cas-server version {{VERSION}}
Pypi: https://pypi.org/project/django-cas-server/
github: https://github.com/nitmir/django-cas-server
-->

View File

@ -0,0 +1,26 @@
{% load cas_server %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&#215;</button>
{{error}}
</div>
{% endfor %}
{% for field in form %}{% if not field|is_hidden %}
<div class="form-group
{% if not form.non_field_errors %}
{% if field.errors %} has-error
{% elif form.cleaned_data %} has-success
{% endif %}
{% endif %}"
>{% spaceless %}
{% if field|is_checkbox %}
<div class="checkbox"><label for="{{field.auto_id}}">{{field}}{{field.label}}</label></div>
{% else %}
<label class="control-label" for="{{field.auto_id}}">{{field.label}}</label>
{{field}}
{% endif %}
{% for error in field.errors %}
<span class="help-block">{{error}}</span>
{% endfor %}
{% endspaceless %}</div>
{% else %}{{field}}{% endif %}{% endfor %}

View File

@ -0,0 +1,21 @@
{% extends "cas_server/base.html" %}
{% load i18n %}
{% block content %}
<div class="alert alert-success" role="alert">{% blocktrans %}<h3>Log In Successful</h3>You have successfully logged into the Central Authentication Service.<br/>For security reasons, please Log Out and Exit your web browser when you are done accessing services that require authentication!{% endblocktrans %}</div>
<form class="form-signin" method="get" action="logout">
<div class="checkbox">
<label>
<input type="checkbox" name="all" value="1">{% trans "Log me out from all my sessions" %}
</label>
</div>
{% if settings.CAS_FEDERATE and request.COOKIES.remember_provider %}
<div class="checkbox">
<label>
<input type="checkbox" name="forget_provider" value="1">{% trans "Forget the identity provider" %}
</label>
</div>
{% endif %}
<button class="btn btn-danger btn-block btn-lg" type="submit">{% trans "Logout" %}</button>
</form>
{% endblock %}

View File

@ -0,0 +1,33 @@
{% extends "cas_server/base.html" %}
{% load i18n %}
{% block ante_messages %}
{% if auto_submit %}<noscript>{% endif %}
<h2 class="form-signin-heading">{% trans "Please log in" %}</h2>
{% if auto_submit %}</noscript>{% endif %}
{% endblock %}
{% block content %}
<div class="alert alert-warning">
{% trans "If you don't have any Note Kfet account, please follow <a href='/accounts/signup'>this link to sign up</a>." %}
</div>
<form class="form-signin" method="post" id="login_form"{% if post_url %} action="{{post_url}}"{% endif %}>
{% csrf_token %}
{% include "cas_server/form.html" %}
{% if auto_submit %}<noscript>{% endif %}
<button class="btn btn-primary btn-block btn-lg" type="submit">{% trans "Login" %}</button>
{% if auto_submit %}</noscript>{% endif %}
</form>
{% endblock %}
{% block javascript_inline %}
jQuery(function( $ ){
$("#id_warn").click(function(e){
if($("#id_warn").is(':checked')){
createCookie("warn", "on", 10 * 365);
} else {
eraseCookie("warn");
}
});
});{% if auto_submit %}
document.getElementById('login_form').submit(); // SUBMIT FORM{% endif %}
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends "cas_server/base.html" %}
{% load static %}
{% load i18n %}
{% block content %}
<div class="alert alert-success" role="alert">{{logout_msg}}</div>
{% endblock %}

View File

@ -0,0 +1,5 @@
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
<cas:proxySuccess>
<cas:proxyTicket>{{ticket}}</cas:proxyTicket>
</cas:proxySuccess>
</cas:serviceResponse>

View File

@ -0,0 +1,59 @@
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
IssueInstant="{{ IssueInstant }}"
MajorVersion="1" MinorVersion="1" Recipient="{{ Recipient }}"
ResponseID="{{ ResponseID }}">
<Status>
<StatusCode Value="samlp:Success">
</StatusCode>
</Status>
<Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="{{ResponseID}}"
IssueInstant="{{IssueInstant}}" Issuer="localhost" MajorVersion="1"
MinorVersion="1">
<Conditions NotBefore="{{IssueInstant}}" NotOnOrAfter="{{expireInstant}}">
<AudienceRestrictionCondition>
<Audience>
{{Recipient}}
</Audience>
</AudienceRestrictionCondition>
</Conditions>
<AttributeStatement>
<Subject>
<NameIdentifier>{{username}}</NameIdentifier>
<SubjectConfirmation>
<ConfirmationMethod>
urn:oasis:names:tc:SAML:1.0:cm:artifact
</ConfirmationMethod>
</SubjectConfirmation>
</Subject>
<Attribute AttributeName="authenticationDate" AttributeNamespace="http://www.ja-sig.org/products/cas/">
<AttributeValue>{{auth_date}}</AttributeValue>
</Attribute>
<Attribute AttributeName="longTermAuthenticationRequestTokenUsed" AttributeNamespace="http://www.ja-sig.org/products/cas/">
<AttributeValue>false</AttributeValue>{# we do not support long-term (Remember-Me) auth #}
</Attribute>
<Attribute AttributeName="isFromNewLogin" AttributeNamespace="http://www.ja-sig.org/products/cas/">
<AttributeValue>{{is_new_login}}</AttributeValue>
</Attribute>
{% for name, value in attributes %} <Attribute AttributeName="{{name}}" AttributeNamespace="http://www.ja-sig.org/products/cas/">
<AttributeValue>{{value}}</AttributeValue>
</Attribute>
{% endfor %} </AttributeStatement>
<AuthenticationStatement AuthenticationInstant="{{IssueInstant}}"
AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
<Subject>
<NameIdentifier>{{username}}</NameIdentifier>
<SubjectConfirmation>
<ConfirmationMethod>
urn:oasis:names:tc:SAML:1.0:cm:artifact
</ConfirmationMethod>
</SubjectConfirmation>
</Subject>
</AuthenticationStatement>
</Assertion>
</Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

View File

@ -0,0 +1,14 @@
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
IssueInstant="{{ IssueInstant }}"
MajorVersion="1" MinorVersion="1" Recipient="{{ Recipient }}"
ResponseID="{{ ResponseID }}">
<Status>
<StatusCode Value="samlp:{{code}}">{{msg}}</StatusCode>
</Status>
</Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

View File

@ -0,0 +1,19 @@
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
<cas:authenticationSuccess>
<cas:user>{{username}}</cas:user>
<cas:attributes>
<cas:authenticationDate>{{auth_date}}</cas:authenticationDate>
<cas:longTermAuthenticationRequestTokenUsed>false</cas:longTermAuthenticationRequestTokenUsed>{# we do not support long-term (Remember-Me) auth #}
<cas:isFromNewLogin>{{is_new_login}}</cas:isFromNewLogin>
{% for key, value in attributes %} <cas:{{key}}>{{value}}</cas:{{key}}>
{% endfor %} </cas:attributes>
<cas:attribute name="authenticationDate" value="{{auth_date}}"/>
<cas:attribute name="longTermAuthenticationRequestTokenUsed" value="false"/>
<cas:attribute name="isFromNewLogin" value="{{is_new_login}}"/>
{% for key, value in attributes %} <cas:attribute name="{{key}}" value="{{value}}"/>
{% endfor %}{% if proxyGrantingTicket %} <cas:proxyGrantingTicket>{{proxyGrantingTicket}}</cas:proxyGrantingTicket>
{% endif %}{% if proxies %} <cas:proxies>
{% for proxy in proxies %} <cas:proxy>{{proxy}}</cas:proxy>
{% endfor %} </cas:proxies>
{% endif %} </cas:authenticationSuccess>
</cas:serviceResponse>

View File

@ -0,0 +1,3 @@
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
<cas:authenticationFailure code="{{code}}">{{msg}}</cas:authenticationFailure>
</cas:serviceResponse>

View File

@ -0,0 +1,11 @@
{% extends "cas_server/base.html" %}
{% load static %}
{% load i18n %}
{% block content %}
<form class="form-signin" method="post">
{% csrf_token %}
{% include "cas_server/form.html" %}
<button class="btn btn-primary btn-block btn-lg" type="submit">{% trans "Connect to the service" %}</button>
</form>
{% endblock %}

View File

@ -0,0 +1,5 @@
{% load crispy_forms_tags %}
{% load i18n %}
<h2>{% trans "Field filters" %}</h2>
{% crispy filter.form %}

View File

@ -0,0 +1,6 @@
{% load i18n %}
<h2>{% trans "Field filters" %}</h2>
<form class="form" action="" method="get">
{{ filter.form.as_p }}
<button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
</form>

View File

@ -0,0 +1 @@
{% for widget in widget.subwidgets %}{% include widget.template_name %}{% if forloop.first %}-{% endif %}{% endfor %}

View File

@ -1,62 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% load pretty_money %}
{% block content %}
<p><a class="btn btn-primary" href="{% url 'member:club_list' %}">Clubs</a></p>
<h3 class="text-center"> Club {{ object.name }}</h3>
<dl>
<dt>{% trans 'Membership starts on' %}</dt>
<dd>{{ club.membership_start }}</dd>
<dt>{% trans 'Membership ends on' %}</dt>
<dd>{{ club.membership_end }}</dd>
<dt>{% trans 'Membership duration' %}</dt>
<dd>{{ club.membership_duration }}</dd>
<dt> Aliases </dt>
<dd>{{ club.note.aliases_set.all }}</dd>
<dt>{% trans 'balance' %}</dt>
<dd>{{ club.note.balance | pretty_money }}</dd>
{% extends "member/noteowner_detail.html" %}
</dl>
{% block profile_info %}
{% include "member/club_info.html" %}
{% endblock %}
<div class="btn-group" role="group">
<a class="btn btn-primary" href="{% url 'member:club_add_member' pk=object.pk %}"> Ajouter des membres </a>
<a class="btn btn-primary" href="{% url 'member:club_add_member' pk=object.pk %}"> Modifier les informations </a>
<a class="btn btn-primary" href="{% url 'member:club_add_member' pk=object.pk %}"> Ajouter des roles </a>
</div>
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<i class="fa fa-users"></i> Membres du club
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordionExample">
<div class="card-body">
{% render_table member_list %}
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h5 class="mb-0">
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</button>
</h5>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
{% render_table history_list %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block profile_content %}
{% include "member/club_tables.html" %}
{% endblock %}

View File

@ -1,11 +1,11 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<p><a class="btn btn-default" href="{% url 'note:template_list' %}">Template Listing</a></p>
<form method="post">
{% csrf_token %}
{{form|crispy}}
<button class="btn btn-primary" type="submit">Submit</button>
<button class="btn btn-primary" type="submit">{% trans "Submit" %}</button>
</form>
{% endblock %}

View File

@ -0,0 +1,32 @@
{% load i18n static pretty_money %}
<div class="card bg-light shadow">
<div class="card-top text-center">
<a href="{% url 'member:club_update_pic' club.pk %}">
<img src="{{ club.note.display_image.url }}" class="img-thumbnail mt-2" >
</a>
</div>
<div class="card-body" id="profile_infos">
<dl class="row">
<dt class="col-xl-6">{% trans 'name'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.name}}</dd>
<dt class="col-xl-6">{% trans 'membership start'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_start }}</dd>
<dt class="col-xl-6">{% trans 'membership end'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_end }}</dd>
<dt class="col-xl-6">{% trans 'membership duration'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_duration }}</dd>
<dt class="col-xl-6">{% trans 'membership fee'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_fee|pretty_money }}</dd>
<dt class="col-xl-6"><a href="{% url 'member:user_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
<dt class="col-xl-3">{% trans 'email'|capfirst %}</dt>
<dd class="col-xl-9"><a href="mailto:{{ club.email }}">{{ club.email}}</a></dd>
</dl>
</div>
</div>

View File

@ -1,15 +1,66 @@
{% extends "base.html" %}
{% load render_table from django_tables2 %}
{% load i18n %}
{% block content %}
{% render_table table %}
<a class="btn btn-primary" href="{% url 'member:club_create' %}">New Club</a>
<div class="row justify-content-center mb-4">
<div class="col-md-10 text-center">
<h4>
{% trans "search clubs" %}
</h4>
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/>
<hr>
<a class="btn btn-primary text-center my-4" href="{% url 'member:club_create' %}">{% trans "Créer un club" %}</a>
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-10">
<div class="card card-border shadow">
<div class="card-header text-center">
<h5> {% trans "club listing "%}</h5>
</div>
<div class="card-body px-0 py-0" id="club_table">
{% render_table table %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block extrajavascript %}
<script type="text/javascript">
function getInfo() {
var asked = $("#search_field").val();
/* on ne fait la requête que si on a au moins un caractère pour chercher */
var sel = $(".table-row");
if (asked.length >= 1) {
$.getJSON("/api/members/club/?format=json&search="+asked, function(buttons){
let selected_id = buttons.results.map((a => "#row-"+a.id));
console.log(selected_id.join());
$(".table-row,"+selected_id.join()).show();
$(".table-row").not(selected_id.join()).hide();
});
}else{
// show everything
$('table tr').show();
}
}
var timer;
var timer_on;
/* Fontion appelée quand le texte change (délenche le timer) */
function search_field_moved(secondfield) {
if (timer_on) { // Si le timer a déjà été lancé, on réinitialise le compteur.
clearTimeout(timer);
timer = setTimeout("getInfo(" + secondfield + ")", 300);
}
else { // Sinon, on le lance et on enregistre le fait qu'il tourne.
timer = setTimeout("getInfo(" + secondfield + ")", 300);
timer_on = true;
}
}
// clickable row
$(document).ready(function($) {
$(".table-row").click(function() {
window.document.location = $(this).data("href");

View File

@ -0,0 +1,10 @@
{% extends "member/club_detail.html" %}
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
{% block profile_info %}
{% include "member/club_info.html" %}
{% endblock%}
{% block profile_content%}
{% include "member/picture_update.html" %}
{% endblock%}

View File

@ -0,0 +1,31 @@
{% load render_table from django_tables2 %}
{% load i18n %}
<div class="accordion shadow" id="accordionProfile">
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="btn btn-link stretched-link font-weight-bold"
data-toggle="collapse" data-target="#clubListCollapse"
aria-expanded="true" aria-controls="clubListCollapse">
<i class="fa fa-users"></i> {% trans "Member of the Club" %}
</a>
</div>
<div id="clubListCollapse" class="collapse show" style="overflow:auto hidden" aria-labelledby="clubListHeading" data-parent="#accordionProfile">
{% render_table member_list %}
</div>
</div>
<div class="card">
<div class="card-header position-relative" id="historyListHeading">
<a class="btn btn-link stretched-link collapsed font-weight-bold"
data-toggle="collapse" data-target="#historyListCollapse"
aria-expanded="false" aria-controls="historyListCollapse">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="historyListCollapse" class="collapse" style="overflow:auto hidden" aria-labelledby="historyListHeading" data-parent="#accordionProfile">
<div id="history_list">
{% render_table history_list %}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% load pretty_money %}
{% block content %}
<div class="row mt-4">
<div class="col-md-3 mb-4">
{% block profile_info %}
{% endblock %}
</div>
<div class="col-md-9">
{% block profile_content %}
{% endblock %}
</div>
</div>
{% endblock %}
{% block extrajavascript %}
<script>
function refreshhistory() {
$("#history_list").load("{% url 'member:user_detail' pk=object.pk %} #history_list");
$("#profile_infos").load("{% url 'member:user_detail' pk=object.pk %} #profile_infos");
}
</script>
{% endblock %}

View File

@ -0,0 +1,95 @@
{% load i18n crispy_forms_tags %}
{% block profile_content %}
<div class="text-center">
<form method="post" enctype="multipart/form-data" id="formUpload">
{% csrf_token %}
{{ form |crispy }}
</form>
</div>
<!-- MODAL TO CROP THE IMAGE -->
<div class="modal fade" id="modalCrop">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<img src="" id="modal-image" style="max-width: 100%;">
</div>
<div class="modal-footer">
<div class="btn-group pull-left" role="group">
<button type="button" class="btn btn-default" id="js-zoom-in">
<span class="glyphicon glyphicon-zoom-in"></span>
</button>
<button type="button" class="btn btn-default js-zoom-out">
<span class="glyphicon glyphicon-zoom-out"></span>
</button>
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">Nevermind</button>
<button type="button" class="btn btn-primary js-crop-and-upload">Crop and upload</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extracss %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.css" rel="stylesheet">
{% endblock %}
{% block extrajavascript%}
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-cropper@1.0.1/dist/jquery-cropper.min.js"></script>
<script>
$(function () {
/* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
$("#id_image").change(function (e) {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#modal-image").attr("src", e.target.result);
$("#modalCrop").modal("show");
}
reader.readAsDataURL(this.files[0]);
}
});
/* SCRIPTS TO HANDLE THE CROPPER BOX */
var $image = $("#modal-image");
var cropBoxData;
var canvasData;
$("#modalCrop").on("shown.bs.modal", function () {
$image.cropper({
viewMode: 1,
aspectRatio: 1/1,
minCropBoxWidth: 200,
minCropBoxHeight: 200,
ready: function () {
$image.cropper("setCanvasData", canvasData);
$image.cropper("setCropBoxData", cropBoxData);
}
});
}).on("hidden.bs.modal", function () {
cropBoxData = $image.cropper("getCropBoxData");
canvasData = $image.cropper("getCanvasData");
$image.cropper("destroy");
});
$(".js-zoom-in").click(function () {
$image.cropper("zoom", 0.1);
});
$(".js-zoom-out").click(function () {
$image.cropper("zoom", -0.1);
});
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
$(".js-crop-and-upload").click(function () {
var cropData = $image.cropper("getData");
$("#id_x").val(cropData["x"]);
$("#id_y").val(cropData["y"]);
$("#id_height").val(cropData["height"]);
$("#id_width").val(cropData["width"]);
$("#formUpload").submit();
});
});
</script>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends "member/profile_detail.html" %}
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
{% block profile_content %}
<div class="d-flex justify-content-center">
<form class=" text-center form my-2" action="" method="post">
{% csrf_token %}
{{ form |crispy }}
<button class="btn btn-primary mx-2" type="submit">
{% trans "Add alias" %}
</button>
</form>
</div>
<div class="card bg-light shadow">
<div class="card-body">
{% render_table aliases %}
</div>
</div>
{% endblock %}

View File

@ -1,77 +1,9 @@
{% extends "base.html" %}
{% load i18n static pretty_money django_tables2 %}
{% extends "member/noteowner_detail.html" %}
{% block content %}
<div class="row mt-4">
<div class="col-md-3 mb-4">
<div class="card bg-light shadow">
<img src="{{ object.note.display_image }}" class="card-img-top" alt="">
<div class="card-body">
<dl class="row">
<dt class="col-xl-6">{% trans 'name'|capfirst %}, {% trans 'first name' %}</dt>
<dd class="col-xl-6">{{ object.last_name }} {{ object.first_name }}</dd>
<dt class="col-xl-6">{% trans 'username'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.username }}</dd>
<dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="small" href="{% url 'password_change' %}">
{% trans 'Change password' %}
</a>
</dd>
<dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.section }}</dd>
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.address }}</dd>
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.note.balance | pretty_money }}</dd>
<dt class="col-xl-6">{% trans 'aliases'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.note.alias_set.all|join:", " }}</dd>
</dl>
{% if object.pk == user.pk %}
<a class="small" href="{% url 'member:auth_token' %}">{% trans 'Manage auth token' %}</a>
{% endif %}
</div>
<div class="card-footer">
<a class="btn btn-primary btn-sm" href="{% url 'member:user_update_profile' object.pk %}">{% trans 'Update Profile' %}</a>
</div>
</div>
</div>
<div class="col-md-9">
<div class="accordion shadow" id="accordionProfile">
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="btn btn-link stretched-link font-weight-bold"
data-toggle="collapse" data-target="#clubListCollapse"
aria-expanded="true" aria-controls="clubListCollapse">
<i class="fa fa-users"></i> {% trans "View my memberships" %}
</a>
</div>
<div id="clubListCollapse" class="collapse show" style="overflow:auto hidden" aria-labelledby="clubListHeading" data-parent="#accordionProfile">
{% render_table club_list %}
</div>
</div>
<div class="card">
<div class="card-header position-relative" id="historyListHeading">
<a class="btn btn-link stretched-link collapsed font-weight-bold"
data-toggle="collapse" data-target="#historyListCollapse"
aria-expanded="false" aria-controls="historyListCollapse">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="historyListCollapse" class="collapse" style="overflow:auto hidden" aria-labelledby="historyListHeading" data-parent="#accordionProfile">
{% render_table history_list %}
</div>
</div>
</div>
</div>
</div>
{% block profile_info %}
{% include "member/profile_info.html" %}
{% endblock %}
{% block profile_content %}
{% include "member/profile_tables.html" %}
{% endblock %}

View File

@ -0,0 +1,48 @@
{% load i18n static pretty_money %}
<div class="card bg-light shadow">
<div class="card-top text-center">
<a href="{% url 'member:user_update_pic' object.pk %}">
<img src="{{ object.note.display_image.url }}" class="img-thumbnail mt-2" >
</a>
</div>
<div class="card-body" id="profile_infos">
<dl class="row">
<dt class="col-xl-6">{% trans 'name'|capfirst %}, {% trans 'first name' %}</dt>
<dd class="col-xl-6">{{ object.last_name }} {{ object.first_name }}</dd>
<dt class="col-xl-6">{% trans 'username'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.username }}</dd>
<dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="small" href="{% url 'password_change' %}">
{% trans 'Change password' %}
</a>
</dd>
<dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.section }}</dd>
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.address }}</dd>
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.note.balance | pretty_money }}</dd>
<dt class="col-xl-6"> <a href="{% url 'member:user_alias' object.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
</dl>
{% if object.pk == user.pk %}
<a class="small" href="{% url 'member:auth_token' %}">{% trans 'Manage auth token' %}</a>
{% endif %}
</div>
<div class="card-footer text-center">
<a class="btn btn-primary btn-sm" href="{% url 'member:user_update_profile' object.pk %}">{% trans 'Update Profile' %}</a>
{% url 'member:user_detail' object.pk as user_profile_url %}
{%if request.get_full_path != user_profile_url %}
<a class="btn btn-primary btn-sm" href="{{ user_profile_url }}">{% trans 'View Profile' %}</a>
{% endif %}
</div>
</div>

View File

@ -0,0 +1,10 @@
{% extends "member/noteowner_detail.html" %}
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
{% block profile_info %}
{% include "member/profile_info.html" %}
{% endblock%}
{% block profile_content%}
{% include "member/picture_update.html" %}
{% endblock%}

View File

@ -0,0 +1,31 @@
{% load render_table from django_tables2 %}
{% load i18n %}
<div class="accordion shadow" id="accordionProfile">
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="btn btn-link stretched-link font-weight-bold"
data-toggle="collapse" data-target="#clubListCollapse"
aria-expanded="true" aria-controls="clubListCollapse">
<i class="fa fa-users"></i> {% trans "View my memberships" %}
</a>
</div>
<div id="clubListCollapse" class="collapse show" style="overflow:auto hidden" aria-labelledby="clubListHeading" data-parent="#accordionProfile">
{% render_table club_list %}
</div>
</div>
<div class="card">
<div class="card-header position-relative" id="historyListHeading">
<a class="btn btn-link stretched-link collapsed font-weight-bold"
data-toggle="collapse" data-target="#historyListCollapse"
aria-expanded="false" aria-controls="historyListCollapse">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="historyListCollapse" class="collapse" style="overflow:auto hidden" aria-labelledby="historyListHeading" data-parent="#accordionProfile">
<div id="history_list">
{% render_table history_list %}
</div>
</div>
</div>
</div>

View File

@ -2,16 +2,16 @@
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% load i18n %}
{% block title %}Sign Up{% endblock %}
{% block title %}{% trans "Sign up" %}{% endblock %}
{% block content %}
<h2>Sign up</h2>
<h2>{% trans "Sign up" %}</h2>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
{{ profile_form|crispy }}
<button class="btn btn-success" type="submit">
{% trans "Sign Up" %}
{% trans "Sign up" %}
</button>
</form>
{% endblock %}

View File

@ -1,97 +1,171 @@
{% extends "base.html" %}
{% load i18n static pretty_money %}
{% load i18n static pretty_money django_tables2 %}
{# Remove page title #}
{% block contenttitle %}{% endblock %}
{% block content %}
{# Regroup buttons under categories #}
{% regroup transaction_templates by category as categories %}
<form method="post" onsubmit="window.onbeforeunload=null">
{% csrf_token %}
<div class="row">
<div class="col-sm-5 mb-4">
{% if form.non_field_errors %}
<p class="errornote">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</p>
{% endif %}
{% for field in form %}
<div class="form-row{% if field.errors %} errors{% endif %}">
{{ field.errors }}
<div>
{{ field.label_tag }}
{% if field.is_readonly %}
<div class="readonly">{{ field.contents }}</div>
{% else %}
{{ field }}
{% endif %}
{% if field.field.help_text %}
<div class="help">{{ field.field.help_text|safe }}</div>
{% endif %}
<div class="row mt-4">
<div class="col-sm-5 col-md-4" id="infos_div">
<div class="row">
{# User details column #}
<div class="col-xl-5" id="note_infos_div">
<div class="card border-success shadow mb-4">
<img src="/media/pic/default.png"
id="profile_pic" alt="" class="img-fluid rounded mx-auto d-block">
<div class="card-body text-center">
<span id="user_note"></span>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="col-sm-7">
<div class="card text-center shadow">
{# Tabs for button categories #}
<div class="card-header">
<ul class="nav nav-tabs nav-fill card-header-tabs">
{% for category in categories %}
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#{{ category.grouper|slugify }}">
{{ category.grouper }}
</a>
</li>
{% endfor %}
{# User selection column #}
<div class="col-xl-7" id="user_select_div">
<div class="card border-success shadow mb-4">
<div class="card-header">
<p class="card-text font-weight-bold">
{% trans "Select emitters" %}
</p>
</div>
<ul class="list-group list-group-flush" id="note_list">
</ul>
</div>
{# Tabs content #}
<div class="card-body">
<div class="tab-content">
{% for category in categories %}
<div class="tab-pane" id="{{ category.grouper|slugify }}">
<div class="d-inline-flex flex-wrap justify-content-center">
{% for button in category.list %}
<button class="btn btn-outline-dark rounded-0 flex-fill"
name="button" value="{{ button.name }}">
{{ button.name }} ({{ button.amount | pretty_money }})
</button>
{% endfor %}
</div>
</div>
{% endfor %}
<div class="card-body">
<input class="form-control mx-auto d-block" type="text" id="note" />
<ul class="list-group list-group-flush" id="alias_matched">
</ul>
</div>
</div>
</div>
<div class="col-xl-5" id="consos_list_div">
<div class="card border-info shadow mb-4">
<div class="card-header">
<p class="card-text font-weight-bold">
{% trans "Select consumptions" %}
</p>
</div>
<ul class="list-group list-group-flush" id="consos_list">
</ul>
<button id="consume_all" class="form-control btn btn-primary">
{% trans "Consume!" %}
</button>
</div>
</div>
</div>
</div>
</form>
{# Buttons column #}
<div class="col-sm-7 col-md-8" id="buttons_div">
{# Show last used buttons #}
<div class="card shadow mb-4">
<div class="card-header">
<p class="card-text font-weight-bold">
{% trans "Most used buttons" %}
</p>
</div>
<div class="card-body text-nowrap" style="overflow:auto hidden">
<div class="d-inline-flex flex-wrap justify-content-center" id="most_used">
{% for button in most_used %}
{% if button.display %}
<button class="btn btn-outline-dark rounded-0 flex-fill"
id="most_used_button{{ button.id }}" name="button" value="{{ button.name }}">
{{ button.name }} ({{ button.amount | pretty_money }})
</button>
{% endif %}
{% endfor %}
</div>
</div>
</div>
{# Regroup buttons under categories #}
{% regroup transaction_templates by category as categories %}
<div class="card border-primary text-center shadow mb-4">
{# Tabs for button categories #}
<div class="card-header">
<ul class="nav nav-tabs nav-fill card-header-tabs">
{% for category in categories %}
<li class="nav-item">
<a class="nav-link font-weight-bold" data-toggle="tab" href="#{{ category.grouper|slugify }}">
{{ category.grouper }}
</a>
</li>
{% endfor %}
</ul>
</div>
{# Tabs content #}
<div class="card-body">
<div class="tab-content">
{% for category in categories %}
<div class="tab-pane" id="{{ category.grouper|slugify }}">
<div class="d-inline-flex flex-wrap justify-content-center">
{% for button in category.list %}
{% if button.display %}
<button class="btn btn-outline-dark rounded-0 flex-fill"
id="button{{ button.id }}" name="button" value="{{ button.name }}">
{{ button.name }} ({{ button.amount | pretty_money }})
</button>
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
{# Mode switch #}
<div class="card-footer border-primary">
<a class="btn btn-sm btn-secondary float-left" href="{% url 'note:template_list' %}">
<i class="fa fa-edit"></i> {% trans "Edit" %}
</a>
<div class="btn-group btn-group-toggle float-right" data-toggle="buttons">
<label for="single_conso" class="btn btn-sm btn-outline-primary active">
<input type="radio" name="conso_type" id="single_conso" checked>
{% trans "Single consumptions" %}
</label>
<label for="double_conso" class="btn btn-sm btn-outline-primary">
<input type="radio" name="conso_type" id="double_conso">
{% trans "Double consumptions" %}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow mb-4" id="history">
<div class="card-header">
<p class="card-text font-weight-bold">
{% trans "Recent transactions history" %}
</p>
</div>
{% render_table table %}
</div>
{% endblock %}
{% block extrajavascript %}
<script type="text/javascript" src="/static/js/consos.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// If hash of a category in the URL, then select this category
// else select the first one
if (location.hash) {
$("a[href='" + location.hash + "']").tab("show");
} else {
$("a[data-toggle='tab']").first().tab("show");
}
{% for button in most_used %}
{% if button.display %}
$("#most_used_button{{ button.id }}").click(function() {
addConso({{ button.destination.id }}, {{ button.amount }},
{{ polymorphic_ctype }}, {{ button.category.id }}, "{{ button.category.name }}",
{{ button.id }}, "{{ button.name }}");
});
{% endif %}
{% endfor %}
// When selecting a category, change URL
$(document.body).on("click", "a[data-toggle='tab']", function(event) {
location.hash = this.getAttribute("href");
});
});
{% for button in transaction_templates %}
{% if button.display %}
$("#button{{ button.id }}").click(function() {
addConso({{ button.destination.id }}, {{ button.amount }},
{{ polymorphic_ctype }}, {{ button.category.id }}, "{{ button.category.name }}",
{{ button.id }}, "{{ button.name }}");
});
{% endif %}
{% endfor %}
</script>
{% endblock %}

View File

@ -3,35 +3,192 @@
SPDX-License-Identifier: GPL-2.0-or-later
{% endcomment %}
{% load i18n static %}
{% load i18n static django_tables2 perms %}
{% block content %}
<form method="post" onsubmit="window.onbeforeunload=null">{% csrf_token %}
{% if form.non_field_errors %}
<p class="errornote">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</p>
{% endif %}
<fieldset class="module aligned">
{% for field in form %}
<div class="form-row{% if field.errors %} errors{% endif %}">
{{ field.errors }}
<div>
{{ field.label_tag }}
{% if field.is_readonly %}
<div class="readonly">{{ field.contents }}</div>
{% else %}
{{ field }}
{% endif %}
{% if field.field.help_text %}
<div class="help">{{ field.field.help_text|safe }}</div>
{% endif %}
<div class="row">
<div class="col-xl-12">
<div class="btn-group btn-group-toggle" style="width: 100%; padding: 0 0 2em 0" data-toggle="buttons">
<label for="type_gift" class="btn btn-sm btn-outline-primary active">
<input type="radio" name="transaction_type" id="type_gift" checked>
{% trans "Gift" %}
</label>
<label for="type_transfer" class="btn btn-sm btn-outline-primary">
<input type="radio" name="transaction_type" id="type_transfer">
{% trans "Transfer" %}
</label>
{% if "note.notespecial"|not_empty_model_list %}
<label for="type_credit" class="btn btn-sm btn-outline-primary">
<input type="radio" name="transaction_type" id="type_credit">
{% trans "Credit" %}
</label>
<label type="type_debit" class="btn btn-sm btn-outline-primary">
<input type="radio" name="transaction_type" id="type_debit">
{% trans "Debit" %}
</label>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-xl-4" id="note_infos_div">
<div class="card border-success shadow mb-4">
<img src="/media/pic/default.png"
id="profile_pic" alt="" class="img-fluid rounded mx-auto d-block">
<div class="card-body text-center">
<span id="user_note"></span>
</div>
</div>
</div>
<div class="col-md-4" id="emitters_div" style="display: none;">
<div class="card border-success shadow mb-4">
<div class="card-header">
<p class="card-text font-weight-bold">
{% trans "Select emitters" %}
</p>
</div>
<ul class="list-group list-group-flush" id="source_note_list">
</ul>
<div class="card-body">
<input class="form-control mx-auto d-block" type="text" id="source_note" />
<ul class="list-group list-group-flush" id="source_alias_matched">
</ul>
</div>
</div>
</div>
{% if "note.notespecial"|not_empty_model_list %}
<div class="col-md-4" id="external_div" style="display: none;">
<div class="card border-success shadow mb-4">
<div class="card-header">
<p class="card-text font-weight-bold">
{% trans "External payment" %}
</p>
</div>
<ul class="list-group list-group-flush" id="source_note_list">
</ul>
<div class="card-body">
<div class="form-row">
<div class="col-md-12">
<label for="credit_type">{% trans "Transfer type" %} :</label>
<select id="credit_type" class="custom-select">
{% for special_type in special_types %}
<option value="{{ special_type.id }}">{{ special_type.special_type }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-row">
<div class="col-md-12">
<label for="last_name">{% trans "Name" %} :</label>
<input type="text" id="last_name" class="form-control" />
</div>
</div>
<div class="form-row">
<div class="col-md-12">
<label for="first_name">{% trans "First name" %} :</label>
<input type="text" id="first_name" class="form-control" />
</div>
</div>
<div class="form-row">
<div class="col-md-12">
<label for="bank">{% trans "Bank" %} :</label>
<input type="text" id="bank" class="form-control" />
</div>
</div>
</div>
</div>
{% endfor %}
</fieldset>
<input type="submit" value="{% trans 'Transfer' %}">
</form>
</div>
{% endif %}
<div class="col-md-8" id="dests_div">
<div class="card border-info shadow mb-4">
<div class="card-header">
<p class="card-text font-weight-bold" id="dest_title">
{% trans "Select receivers" %}
</p>
</div>
<ul class="list-group list-group-flush" id="dest_note_list">
</ul>
<div class="card-body">
<input class="form-control mx-auto d-block" type="text" id="dest_note" />
<ul class="list-group list-group-flush" id="dest_alias_matched">
</ul>
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="amount">{% trans "Amount" %} :</label>
<div class="input-group">
<input class="form-control mx-auto d-block" type="number" min="0" step="0.01" id="amount" />
<div class="input-group-append">
<span class="input-group-text"></span>
</div>
</div>
</div>
<div class="form-group col-md-6">
<label for="reason">{% trans "Reason" %} :</label>
<input class="form-control mx-auto d-block" type="text" id="reason" required />
</div>
</div>
<div class="form-row">
<div class="col-md-12">
<button id="transfer" class="form-control btn btn-primary">{% trans 'Transfer' %}</button>
</div>
</div>
<div class="card shadow mb-4" id="history">
<div class="card-header">
<p class="card-text font-weight-bold">
{% trans "Recent transactions history" %}
</p>
</div>
{% render_table table %}
</div>
{% endblock %}
{% block extrajavascript %}
<script>
TRANSFER_POLYMORPHIC_CTYPE = {{ polymorphic_ctype }};
SPECIAL_TRANSFER_POLYMORPHIC_CTYPE = {{ special_polymorphic_ctype }};
user_id = {{ user.note.pk }};
$("#type_gift").click(function() {
$("#emitters_div").hide();
$("#external_div").hide();
$("#dests_div").attr('class', 'col-md-8');
$("#dest_title").text("{% trans "Select receivers" %}");
});
$("#type_transfer").click(function() {
$("#external_div").hide();
$("#emitters_div").show();
$("#dests_div").attr('class', 'col-md-4');
$("#dest_title").text("{% trans "Select receivers" %}");
});
$("#type_credit").click(function() {
$("#emitters_div").hide();
$("#external_div").show();
$("#dests_div").attr('class', 'col-md-4');
$("#dest_title").text("{% trans "Credit note" %}");
});
$("#type_debit").click(function() {
$("#emitters_div").hide();
$("#external_div").show();
$("#dests_div").attr('class', 'col-md-4');
$("#dest_title").text("{% trans "Debit note" %}");
});
</script>
<script src="/static/js/transfer.js"></script>
{% endblock %}

View File

@ -1,8 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<p><a class="btn btn-default" href="{% url 'note:template_list' %}">Template Listing</a></p>
<p><a class="btn btn-default" href="{% url 'note:template_list' %}">{% trans "Buttons list" %}</a></p>
<form method="post">
{% csrf_token %}
{{form|crispy}}

View File

@ -1,23 +1,79 @@
{% extends "base.html" %}
{% load pretty_money %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block content %}
<table class="table">
<tr>
<td>ID</td><td>Nom</td>
<td>Destinataire</td>
<td>Montant</td>
<td>Catégorie</td>
</tr>
{% for object in object_list %}
<tr>
<td>{{object.pk}}</td>
<td><a href="{{object.get_absolute_url}}">{{ object.name }}</a></td>
<td>{{ object.destination }}</td>
<td>{{ object.amount | pretty_money }}</td>
<td>{{ object.template_type }}</td>
</tr>
{% endfor %}
</table>
<a class="btn btn-primary" href="{% url 'note:template_create' %}">Créer un bouton</a>
<div class="row justify-content-center mb-4">
<div class="col-md-10 text-center">
<h4>
{% trans "search button" %}
</h4>
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/>
<hr>
<a class="btn btn-primary text-center my-4" href="{% url 'note:template_create' %}">Créer un bouton</a>
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-10">
<div class="card card-border shadow">
<div class="card-header text-center">
<h5> {% trans "buttons listing "%}</h5>
</div>
<div class="card-body px-0 py-0" id="buttons_table">
{% render_table table %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block extrajavascript %}
<script>
/* fonction appelée à la fin du timer */
function getInfo() {
var asked = $("#search_field").val();
/* on ne fait la requête que si on a au moins un caractère pour chercher */
var sel = $(".table-row");
if (asked.length >= 1) {
$.getJSON("/api/note/transaction/template/?format=json&search="+asked, function(buttons){
let selected_id = buttons.results.map((a => "#row-"+a.id));
console.log(selected_id.join());
$(".table-row,"+selected_id.join()).show();
$(".table-row").not(selected_id.join()).hide();
});
}else{
// show everything
$('table tr').show();
}
}
var timer;
var timer_on;
/* Fontion appelée quand le texte change (délenche le timer) */
function search_field_moved(secondfield) {
if (timer_on) { // Si le timer a déjà été lancé, on réinitialise le compteur.
clearTimeout(timer);
timer = setTimeout("getInfo(" + secondfield + ")", 300);
}
else { // Sinon, on le lance et on enregistre le fait qu'il tourne.
timer = setTimeout("getInfo(" + secondfield + ")", 300);
timer_on = true;
}
}
// on click of button "delete" , call the API
function delete_button(button_id){
$.ajax({
url:"/api/note/transaction/template/"+button_id+"/",
method:"DELETE",
headers: {"X-CSRFTOKEN": CSRF_TOKEN}
})
.done(function(){
addMsg('{% trans "button successfully deleted "%}','success');
$("#buttons_table").load("{% url 'note:template_list' %} #buttons_table");
})
.fail(function(){
addMsg(' {% trans "Unable to delete button "%} #' + button_id,'danger' )
});
}
</script>
{% endblock %}

View File

@ -16,7 +16,13 @@ SPDX-License-Identifier: GPL-2.0-or-later
{% endblocktrans %}
</p>
{% endif %}
{%url 'cas_login' as cas_url %}
{% if cas_url %}
<div class="alert alert-info">
{% trans "You can also register via the central authentification server " %}
<a href="{{ cas_url }}"> {% trans "using this link "%}</a>
</div>
{%endif%}
<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
{{ form | crispy }}
<input type="submit" value="{% trans 'Log in' %}" class="btn btn-primary">

View File

@ -0,0 +1,107 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load crispy_forms_tags pretty_money %}
{% block content %}
<p><a class="btn btn-default" href="{% url 'treasury:invoice_list' %}">{% trans "Invoices list" %}</a></p>
<form method="post" action="">
{% csrf_token %}
{# Render the invoice form #}
{% crispy form %}
{# The next part concerns the product formset #}
{# Generate some hidden fields that manage the number of products, and make easier the parsing #}
{{ formset.management_form }}
<table class="table table-condensed table-striped">
{# Fill initial data #}
{% for form in formset %}
{% if forloop.first %}
<thead>
<tr>
<th>{{ form.designation.label }}<span class="asteriskField">*</span></th>
<th>{{ form.quantity.label }}<span class="asteriskField">*</span></th>
<th>{{ form.amount.label }}<span class="asteriskField">*</span></th>
</tr>
</thead>
<tbody id="form_body">
{% endif %}
<tr class="row-formset">
<td>{{ form.designation }}</td>
<td>{{ form.quantity }} </td>
<td>
{# Use custom input for amount, with the € symbol #}
<div class="input-group">
<input type="number" name="product_set-{{ forloop.counter0 }}-amount" step="0.01"
id="id_product_set-{{ forloop.counter0 }}-amount"
value="{{ form.instance.amount|cents_to_euros }}">
<div class="input-group-append">
<span class="input-group-text"></span>
</div>
</div>
</td>
{# These fields are hidden but handled by the formset to link the id and the invoice id #}
{{ form.invoice }}
{{ form.id }}
</tr>
{% endfor %}
</tbody>
</table>
{# Display buttons to add and remove products #}
<div class="btn-group btn-block" role="group">
<button type="button" id="add_more" class="btn btn-primary">{% trans "Add product" %}</button>
<button type="button" id="remove_one" class="btn btn-danger">{% trans "Remove product" %}</button>
</div>
<div class="btn-block">
<button type="submit" class="btn btn-block btn-primary">{% trans "Submit" %}</button>
</div>
</form>
<div id="empty_form" style="display: none;">
{# Hidden div that store an empty product form, to be copied into new forms #}
<table class='no_error'>
<tbody id="for_real">
<tr class="row-formset">
<td>{{ formset.empty_form.designation }}</td>
<td>{{ formset.empty_form.quantity }} </td>
<td>
<div class="input-group">
<input type="number" name="product_set-__prefix__-amount" step="0.01"
id="id_product_set-__prefix__-amount">
<div class="input-group-append">
<span class="input-group-text"></span>
</div>
</div>
</td>
{{ formset.empty_form.invoice }}
{{ formset.empty_form.id }}
</tr>
</tbody>
</table>
</div>
{% endblock %}
{% block extrajavascript %}
<script>
{# Script that handles add and remove lines #}
IDS = {};
$("#id_product_set-TOTAL_FORMS").val($(".row-formset").length - 1);
$('#add_more').click(function () {
var form_idx = $('#id_product_set-TOTAL_FORMS').val();
$('#form_body').append($('#for_real').html().replace(/__prefix__/g, form_idx));
$('#id_product_set-TOTAL_FORMS').val(parseInt(form_idx) + 1);
$('#id_product_set-' + parseInt(form_idx) + '-id').val(IDS[parseInt(form_idx)]);
});
$('#remove_one').click(function () {
let form_idx = $('#id_product_set-TOTAL_FORMS').val();
if (form_idx > 0) {
IDS[parseInt(form_idx) - 1] = $('#id_product_set-' + (parseInt(form_idx) - 1) + '-id').val();
$('#form_body tr:last-child').remove();
$('#id_product_set-TOTAL_FORMS').val(parseInt(form_idx) - 1);
}
});
</script>
{% endblock %}

View File

@ -0,0 +1,23 @@
{% extends "base.html" %}
{% load render_table from django_tables2 %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-xl-12">
<div class="btn-group btn-group-toggle" style="width: 100%; padding: 0 0 2em 0" data-toggle="buttons">
<a href="#" class="btn btn-sm btn-outline-primary active">
{% trans "Invoice" %}s
</a>
<a href="{% url "treasury:remittance_list" %}" class="btn btn-sm btn-outline-primary">
{% trans "Remittance" %}s
</a>
</div>
</div>
</div>
{% render_table table %}
<a class="btn btn-primary" href="{% url 'treasury:invoice_create' %}">{% trans "New invoice" %}</a>
{% endblock %}

View File

@ -0,0 +1,186 @@
\nonstopmode
\documentclass[11pt]{article}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{units}
\usepackage{bera}
\usepackage{graphicx}
\usepackage{fancyhdr}
\usepackage{fp}
\usepackage{transparent}
\usepackage{eso-pic}
\def\TVA{0} % Taux de la TVA
\def\TotalHT{0}
\def\TotalTVA{0}
\newcommand{\AjouterProduit}[4]{% Arguments : Désignation, quantité, prix unitaire HT, prix total HT
\FPround{\prix}{#3}{2}
\FPround{\montant}{#4}{2}
\FPadd{\TotalHT}{\TotalHT}{\montant}
\eaddto\ListeProduits{#1 & \prix & #2 & \montant \cr}
}
\newcommand{\AfficheResultat}{%
\ListeProduits
\FPeval{\TotalTVA}{\TotalHT * \TVA / 100}
\FPadd{\TotalTTC}{\TotalHT}{\TotalTVA}
\FPround{\TotalHT}{\TotalHT}{2}
\FPround{\TotalTVA}{\TotalTVA}{2}
\FPround{\TotalTTC}{\TotalTTC}{2}
\global\let\TotalHT\TotalHT
\global\let\TotalTVA\TotalTVA
\global\let\TotalTTC\TotalTTC
\cr \hline
Total HT & & & \TotalHT \cr
TVA \TVA~\% & & & \TotalTVA \cr
\hline \hline
\textbf{Total TTC} & & & \TotalTTC
}
\newcommand*\eaddto[2]{% version développée de \addto
\edef\tmp{#2}%
\expandafter\addto
\expandafter#1%
\expandafter{\tmp}%
}
\newcommand {\ListeProduits}{}
% Logo du BDE
\AddToShipoutPicture*{
\put(0,0){
\parbox[b][\paperheight]{\paperwidth}{%
\vfill
\centering
{\transparent{0.1}\includegraphics[width=\textwidth]{../../static/img/{{ obj.bde }}}}%
\vfill
}
}
}
%%%%%%%%%%%%%%%%%%%%% A MODIFIER DANS LA FACTURE %%%%%%%%%%%%%%%%%%%%%
% Infos Association
\def\MonNom{{"{"}}{{ obj.my_name }}} % Nom de l'association
\def\MonAdresseRue{{"{"}}{{ obj.my_address_street }}} % Adresse de l'association
\def\MonAdresseVille{{"{"}}{{ obj.my_city }}}
% Informations bancaires de l'association
\def\CodeBanque{{"{"}}{{ obj.bank_code|stringformat:".05d" }}}
\def\CodeGuichet{{"{"}}{{ obj.desk_code|stringformat:".05d" }}}
\def\NCompte{{"{"}}{{ obj.account_number|stringformat:".011d" }}}
\def\CleRib{{"{"}}{{ obj.rib_key|stringformat:".02d" }}}
\def\IBAN{FR76\CodeBanque\CodeGuichet\NCompte\CleRib}
\def\CodeBic{{"{"}}{{ obj.bic }}}
\def\FactureNum {{"{"}}{{obj.id}}} % Numéro de facture
\def\FactureAcquittee {% if obj.acquitted %} {oui} {% else %} {non} {% endif %} % Facture acquittée : oui/non
\def\FactureLieu {{"{"}}{{ obj.place }}} % Lieu de l'édition de la facture
\def\FactureDate {{"{"}}{{ obj.date }}} % Date de l'édition de la facture
\def\FactureObjet {{"{"}}{{ obj.object|safe }} } % Objet du document
% Description de la facture
\def\FactureDescr {{"{"}}{{ obj.description|safe }}}
% Infos Client
\def\ClientNom{{"{"}}{{obj.name|safe}}} % Nom du client
\def\ClientAdresse{{"{"}}{{ obj.address|safe }}} % Adresse du client
% Liste des produits facturés : Désignation, quantité, prix unitaire HT
{% for product in products %}
\AjouterProduit{ {{product.designation|safe}}} { {{product.quantity|safe}}} { {{product.amount_euros|safe}}} { {{product.total_euros|safe}}}
{% endfor %}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\geometry{verbose,tmargin=4em,bmargin=8em,lmargin=6em,rmargin=6em}
\setlength{\parindent}{1pt}
\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}
\thispagestyle{fancy}
\pagestyle{fancy}
\setlength{\parindent}{0pt}
\renewcommand{\headrulewidth}{0pt}
\cfoot{
\small{\MonNom ~--~ \MonAdresseRue ~ \MonAdresseVille ~--~ Téléphone : +33(0)6 89 88 56 50\newline
Site web : bde.ens-cachan.fr ~--~ E-mail : tresorerie.bde@lists.crans.org \newline Numéro SIRET : 399 485 838 00011
}
}
\begin{document}
% Logo de la société
% \includegraphics{logo.jpg}
% Nom et adresse de la société
\MonNom \\
\MonAdresseRue \\
\MonAdresseVille
Facture n°\FactureNum
{\addtolength{\leftskip}{10.5cm} %in ERT
\ClientNom \\
\ClientAdresse \\
} %in ERT
\hspace*{10.5cm}
\FactureLieu, le \FactureDate
~\\~\\
\textbf{Objet : \FactureObjet \\}
\textnormal{\FactureDescr}
~\\
\begin{center}
\begin{tabular}{lrrr}
\textbf{Désignation ~~~~~~} & \textbf{Prix unitaire} & \textbf{Quantité} & \textbf{Montant (EUR)} \\
\hline
\AfficheResultat{}
\end{tabular}
\end{center}
~\\
\ifthenelse{\equal{\FactureAcquittee}{oui}}{
Facture acquittée.
}{
À régler par chèque ou par virement bancaire :
\begin{center}
\begin{tabular}{|c c c c|}
\hline
\textbf{Code banque} & \textbf{Code guichet} & \textbf{N° de Compte} & \textbf{Clé RIB}\\
\CodeBanque & \CodeGuichet & \NCompte & \CleRib \\
\hline
\textbf{IBAN N°} & \multicolumn{3}{|l|} \IBAN \\
\hline
\textbf{Code BIC} & \multicolumn{3}{|l|}\CodeBic \\
\hline
\end{tabular}
\end{center}
}
\begin{center}
TVA non applicable, article 293 B du CGI.
\end{center}
\end{document}

View File

@ -0,0 +1,37 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load crispy_forms_tags pretty_money %}
{% load render_table from django_tables2 %}
{% block content %}
<h1>{% trans "Remittance #" %}{{ object.pk }}</h1>
<p><a class="btn btn-default" href="{% url 'treasury:remittance_list' %}">{% trans "Remittances list" %}</a></p>
{% if object.pk %}
<div id="div_id_type" class="form-group"><label for="id_count" class="col-form-label">{% trans "Count" %}</label>
<div class="">
<input type="text" name="count" value="{{ object.count }}" class="textinput textInput form-control" id="id_count" disabled>
</div>
</div>
<div id="div_id_type" class="form-group"><label for="id_amount" class="col-form-label">{% trans "Amount" %}</label>
<div class="">
<input class="textinput textInput form-control" type="text" value="{{ object.amount|pretty_money }}" id="id_amount" disabled>
</div>
</div>
{% endif %}
{% crispy form %}
<hr>
<h2>{% trans "Linked transactions" %}</h2>
{% if special_transactions.data %}
{% render_table special_transactions %}
{% else %}
<div class="alert alert-warning">
{% trans "There is no transaction linked with this remittance." %}
</div>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,56 @@
{% extends "base.html" %}
{% load render_table from django_tables2 %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-xl-12">
<div class="btn-group btn-group-toggle" style="width: 100%; padding: 0 0 2em 0" data-toggle="buttons">
<a href="{% url "treasury:invoice_list" %}" class="btn btn-sm btn-outline-primary">
{% trans "Invoice" %}s
</a>
<a href="#" class="btn btn-sm btn-outline-primary active">
{% trans "Remittance" %}s
</a>
</div>
</div>
</div>
<h2>{% trans "Opened remittances" %}</h2>
{% if opened_remittances.data %}
{% render_table opened_remittances %}
{% else %}
<div class="alert alert-warning">
{% trans "There is no opened remittance." %}
</div>
{% endif %}
<a class="btn btn-primary" href="{% url 'treasury:remittance_create' %}">{% trans "New remittance" %}</a>
<hr>
<h2>{% trans "Transfers without remittances" %}</h2>
{% if special_transactions_no_remittance.data %}
{% render_table special_transactions_no_remittance %}
{% else %}
<div class="alert alert-warning">
{% trans "There is no transaction without any linked remittance." %}
</div>
{% endif %}
<hr>
<h2>{% trans "Transfers with opened remittances" %}</h2>
{% if special_transactions_with_remittance.data %}
{% render_table special_transactions_with_remittance %}
{% else %}
<div class="alert alert-warning">
{% trans "There is no transaction with an opened linked remittance." %}
</div>
{% endif %}
<hr>
<h2>{% trans "Closed remittances" %}</h2>
{% render_table closed_remittances %}
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load crispy_forms_tags pretty_money %}
{% load render_table from django_tables2 %}
{% block content %}
<p><a class="btn btn-default" href="{% url 'treasury:remittance_list' %}">{% trans "Remittances list" %}</a></p>
{% crispy form %}
{% endblock %}