mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 01:12:08 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			309 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
{% extends "base.html" %}
 | 
						|
 | 
						|
{% load i18n static pretty_money django_tables2 %}
 | 
						|
 | 
						|
{# Remove page title #}
 | 
						|
{% block contenttitle %}{% endblock %}
 | 
						|
 | 
						|
{% block content %}
 | 
						|
    <div class="row mt-4">
 | 
						|
        <div class="col-sm-5 col-md-4">
 | 
						|
            <div class="row">
 | 
						|
                {# User details column #}
 | 
						|
                <div class="col-xl-5">
 | 
						|
                    <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>
 | 
						|
 | 
						|
                {# User selection column #}
 | 
						|
                <div class="col-xl-7">
 | 
						|
                    <div class="card border-success shadow mb-4">
 | 
						|
                        <div class="card-header">
 | 
						|
                            <p class="card-text font-weight-bold">
 | 
						|
                                Sélection des émitteurs
 | 
						|
                            </p>
 | 
						|
                        </div>
 | 
						|
                        <ul class="list-group list-group-flush" id="note_list">
 | 
						|
                        </ul>
 | 
						|
                        <div class="card-body">
 | 
						|
                            <input class="rounded mx-auto d-block" type="text" id="note" />
 | 
						|
                            <ul class="list-group list-group-flush" id="alias_matched">
 | 
						|
                            </ul>
 | 
						|
                        </div>
 | 
						|
                    </div>
 | 
						|
                </div>
 | 
						|
            </div>
 | 
						|
        </div>
 | 
						|
 | 
						|
        {# Buttons column #}
 | 
						|
        <div class="col-sm-7 col-md-8">
 | 
						|
            {# Show last used buttons #}
 | 
						|
            <div class="card shadow mb-4">
 | 
						|
                <div class="card-body text-nowrap" style="overflow:auto hidden">
 | 
						|
                    <p class="card-text text-muted font-weight-light font-italic">
 | 
						|
                        Les boutons les plus utilisés s'afficheront ici.
 | 
						|
                    </p>
 | 
						|
                </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> Éditer
 | 
						|
                    </a>
 | 
						|
                    <div class="btn-group btn-group-toggle float-right" data-toggle="buttons">
 | 
						|
                        <label class="btn btn-sm btn-outline-primary active">
 | 
						|
                            <input type="radio" name="options" id="option1" checked>
 | 
						|
                            Consomations simples
 | 
						|
                        </label>
 | 
						|
                        <label class="btn btn-sm btn-outline-primary">
 | 
						|
                            <input type="radio" name="options" id="option2">
 | 
						|
                            Consomations doubles
 | 
						|
                        </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">
 | 
						|
                Historique des transactions récentes
 | 
						|
            </p>
 | 
						|
        </div>
 | 
						|
        {% render_table table %}
 | 
						|
    </div>
 | 
						|
{% endblock %}
 | 
						|
 | 
						|
{% block extracss %}
 | 
						|
    <style>
 | 
						|
        .select2-container{
 | 
						|
            max-width: 100%;
 | 
						|
            min-width: 100%;
 | 
						|
        }
 | 
						|
    </style>
 | 
						|
 | 
						|
    <link href="/static/vendor/select2/dist/css/select2.css" type="text/css" media="screen" rel="stylesheet">
 | 
						|
    <link href="/static/admin/css/autocomplete.css" type="text/css" media="screen" rel="stylesheet">
 | 
						|
    <link href="/static/autocomplete_light/select2.css" type="text/css" media="screen" rel="stylesheet">
 | 
						|
    <script type="text/javascript" src="/static/autocomplete_light/jquery.init.js"></script>
 | 
						|
    <script type="text/javascript" src="/static/vendor/select2/dist/js/select2.full.js"></script>
 | 
						|
    <script type="text/javascript" src="/static/vendor/select2/dist/js/i18n/fr.js"></script>
 | 
						|
    <script type="text/javascript" src="/static/autocomplete_light/autocomplete.init.js"></script>
 | 
						|
    <script type="text/javascript" src="/static/autocomplete_light/forward.js"></script>
 | 
						|
    <script type="text/javascript" src="/static/autocomplete_light/select2.js"></script>
 | 
						|
    <script type="text/javascript" src="/static/autocomplete_light/jquery.post-setup.js"></script>
 | 
						|
{% endblock %}
 | 
						|
 | 
						|
{% block extrajavascript %}
 | 
						|
    <script type="text/javascript">
 | 
						|
        function pretty_money(value) {
 | 
						|
            if (value % 100 === 0)
 | 
						|
                return (value < 0 ? "- " : "") + Math.floor(Math.abs(value) / 100) + " €";
 | 
						|
            else
 | 
						|
                return (value < 0 ? "- " : "") + Math.floor(Math.abs(value) / 100) + " € " + (Math.abs(value) % 100);
 | 
						|
        }
 | 
						|
 | 
						|
        let old_pattern = null;
 | 
						|
        let notes = [];
 | 
						|
        let consos = [];
 | 
						|
 | 
						|
        $(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");
 | 
						|
            }
 | 
						|
 | 
						|
            // When selecting a category, change URL
 | 
						|
            $(document.body).on("click", "a[data-toggle='tab']", function(event) {
 | 
						|
                location.hash = this.getAttribute("href");
 | 
						|
            });
 | 
						|
 | 
						|
            let note_obj = $("#note");
 | 
						|
            note_obj.click(function() {
 | 
						|
                note_obj.val("");
 | 
						|
            });
 | 
						|
            note_obj.keyup(function() {
 | 
						|
                let pattern = note_obj.val();
 | 
						|
                if (pattern === old_pattern || pattern === "")
 | 
						|
                    return;
 | 
						|
 | 
						|
                old_pattern = pattern;
 | 
						|
 | 
						|
                notes = [];
 | 
						|
                let aliases_matched_obj = $("#alias_matched");
 | 
						|
                let aliases_matched_html = "";
 | 
						|
                $.getJSON("/api/note/alias/?format=json&alias=" + pattern + "&search=user|club", function(aliases) {
 | 
						|
                    aliases.results.forEach(function(alias) {
 | 
						|
                        aliases_matched_html += "<li class=\"list-group-item py-1 d-flex justify-content-between align-items-center\"" +
 | 
						|
                            " id=\"alias_" + alias.normalized_name + "\">" + alias.name + "</li>\n";
 | 
						|
                        $.getJSON("/api/note/note/" + alias.note + "/?format=json", function(note) {
 | 
						|
                            notes += note;
 | 
						|
                            let alias_obj = $("#alias_" + alias.normalized_name);
 | 
						|
                            alias_obj.hover(function() {
 | 
						|
                                var name = alias.name;
 | 
						|
                                if (name !== note.name)
 | 
						|
                                    name += " (aka. " + note.name + ")";
 | 
						|
                                $("#user_note").text(name + " : " + pretty_money(note.balance));
 | 
						|
                            if (note.display_image == null)
 | 
						|
                                $("#profile_pic").attr('src', '/media/pic/default.png');
 | 
						|
                            else
 | 
						|
                                $("#profile_pic").attr('src', note.display_image);
 | 
						|
                            });
 | 
						|
 | 
						|
                            alias_obj.click(function() {
 | 
						|
                                note_obj.val("");
 | 
						|
                                var conso = null;
 | 
						|
                                consos.forEach(function(c) {
 | 
						|
                                    if (c[1] === note.id) {
 | 
						|
                                        c[3] += 1;
 | 
						|
                                        conso = c;
 | 
						|
                                    }
 | 
						|
                                });
 | 
						|
                                if (conso == null)
 | 
						|
                                    consos = consos.concat([[alias.name, note.id, note, 1]]);
 | 
						|
                                let note_list = $("#note_list");
 | 
						|
                                let html = "";
 | 
						|
                                consos.forEach(function(conso) {
 | 
						|
                                   html += "<li class=\"list-group-item py-1 d-flex justify-content-between align-items-center\"" +
 | 
						|
                                       " id=\"note_" + conso[1] + "\">" + conso[0] + "<span class=\"badge badge-dark badge-pill\">"
 | 
						|
                                       + conso[3] + "</span></li>\n";
 | 
						|
                                });
 | 
						|
 | 
						|
                                note_list.html(html);
 | 
						|
 | 
						|
                                consos.forEach(function(conso) {
 | 
						|
                                    let line_obj = $("#note_" + conso[1]);
 | 
						|
                                    line_obj.hover(function() {
 | 
						|
                                        $("#user_note").text(conso[0] + " : " + pretty_money(conso[2].balance));
 | 
						|
                                        if (conso[2].display_image == null)
 | 
						|
                                            $("#profile_pic").attr('src', '/media/pic/default.png');
 | 
						|
                                        else
 | 
						|
                                            $("#profile_pic").attr('src', conso[2].display_image);
 | 
						|
                                    });
 | 
						|
 | 
						|
                                    function line_obj_click(c) {
 | 
						|
                                        return (function() {
 | 
						|
                                            let new_consos = [];
 | 
						|
                                            let html = "";
 | 
						|
                                            consos.forEach(function (conso) {
 | 
						|
                                                if (conso[3] > 1 || conso[1] !== c[1]) {
 | 
						|
                                                    conso[3] -= conso[1] === c[1] ? 1 : 0;
 | 
						|
                                                    new_consos = new_consos.concat([conso]);
 | 
						|
                                                    html += "<li class=\"list-group-item py-1 d-flex justify-content-between align-items-center\"" +
 | 
						|
                                                        " id=\"note_" + conso[1] + "\">" + conso[0] + "<span class=\"badge badge-dark badge-pill\">"
 | 
						|
                                                        + conso[3] + "</span></li>\n";
 | 
						|
                                                }
 | 
						|
                                            });
 | 
						|
                                            note_list.html(html);
 | 
						|
                                            consos.forEach(function (conso) {
 | 
						|
                                                $("#note_" + conso[1]).click(line_obj_click(conso));
 | 
						|
                                                line_obj.hover(function() {
 | 
						|
                                                    $("#user_note").text(conso[0] + " : " + pretty_money(conso[2].balance));
 | 
						|
                                                    if (conso[2].display_image == null)
 | 
						|
                                                        $("#profile_pic").attr('src', '/media/pic/default.png');
 | 
						|
                                                    else
 | 
						|
                                                        $("#profile_pic").attr('src', conso[2].display_image);
 | 
						|
                                                });
 | 
						|
                                            });
 | 
						|
                                            consos = new_consos;
 | 
						|
                                        });
 | 
						|
                                    }
 | 
						|
 | 
						|
                                    line_obj.click(line_obj_click(conso));
 | 
						|
                                });
 | 
						|
                            });
 | 
						|
                        });
 | 
						|
                    });
 | 
						|
                    aliases_matched_obj.html(aliases_matched_html);
 | 
						|
                });
 | 
						|
            });
 | 
						|
 | 
						|
            {% for button in transaction_templates %}
 | 
						|
                {% if button.display %}
 | 
						|
                    $("#button{{ button.id }}").click(function() {
 | 
						|
                        consos.forEach(function(conso) {
 | 
						|
                            $.post("/api/note/transaction/transaction/",
 | 
						|
                            {
 | 
						|
                                "csrfmiddlewaretoken": "{{ csrf_token }}",
 | 
						|
                                "quantity": conso[3],
 | 
						|
                                "amount": {{ button.amount }},
 | 
						|
                                "reason": "{{ button.name }} ({{ button.category.name }})",
 | 
						|
                                "valid": true,
 | 
						|
                                "polymorphic_ctype": {{ polymorphic_ctype }},
 | 
						|
                                "resourcetype": "TemplateTransaction",
 | 
						|
                                "source": conso[1],
 | 
						|
                                "destination": {{ button.destination.pk }},
 | 
						|
                                "category": {{ button.category.id }},
 | 
						|
                                "template": {{ button.id }}
 | 
						|
                            }, function () {
 | 
						|
                                consos = [];
 | 
						|
                                $("#note_list").html("");
 | 
						|
                                $("#alias_matched").html("");
 | 
						|
                                $("#profile_pic").attr("src", "/media/pic/default.png");
 | 
						|
                                $("#user_note").text("");
 | 
						|
                                refreshHistory();
 | 
						|
                                refreshBalance();
 | 
						|
                            });
 | 
						|
                        });
 | 
						|
                    });
 | 
						|
                {% endif %}
 | 
						|
            {% endfor %}
 | 
						|
        });
 | 
						|
 | 
						|
        function refreshBalance() {
 | 
						|
            $("#user_balance").load("/ #user_balance");
 | 
						|
        }
 | 
						|
 | 
						|
        function refreshHistory() {
 | 
						|
            $("#history").load("/note/consos/ #history");
 | 
						|
        }
 | 
						|
    </script>
 | 
						|
{% endblock %}
 |