mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-12-24 00:12:23 +00:00
Merge branch 'master' into 'fix-what-i-broke'
# Conflicts: # templates/base.html
This commit is contained in:
commit
46e472ed6d
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "apps/scripts"]
|
||||
path = apps/scripts
|
||||
url = git@gitlab.crans.org:bde/nk20-scripts.git
|
@ -46,6 +46,7 @@ class Profile(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _('user profile')
|
||||
verbose_name_plural = _('user profile')
|
||||
indexes = [ models.Index(fields=['user']) ]
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('user_detail', args=(self.pk,))
|
||||
@ -152,6 +153,7 @@ class Membership(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _('membership')
|
||||
verbose_name_plural = _('memberships')
|
||||
indexes = [ models.Index(fields=['user']) ]
|
||||
|
||||
# @receiver(post_save, sender=settings.AUTH_USER_MODEL)
|
||||
# def save_user_profile(instance, created, **_kwargs):
|
||||
|
@ -6,7 +6,7 @@ from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .models import Alias
|
||||
from .models import Transaction, TransactionTemplate, TemplateTransaction
|
||||
from .models import Transaction, TransactionTemplate
|
||||
|
||||
|
||||
class AliasForm(forms.ModelForm):
|
||||
@ -99,33 +99,3 @@ class TransactionForm(forms.ModelForm):
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class ConsoForm(forms.ModelForm):
|
||||
def save(self, commit=True):
|
||||
button: TransactionTemplate = TransactionTemplate.objects.filter(
|
||||
name=self.data['button']).get()
|
||||
self.instance.destination = button.destination
|
||||
self.instance.amount = button.amount
|
||||
self.instance.reason = '{} ({})'.format(button.name, button.category)
|
||||
self.instance.template = button
|
||||
self.instance.category = button.category
|
||||
super().save(commit)
|
||||
|
||||
class Meta:
|
||||
model = TemplateTransaction
|
||||
fields = ('source',)
|
||||
|
||||
# Le champ d'utilisateur est remplacé par un champ d'auto-complétion.
|
||||
# Quand des lettres sont tapées, une requête est envoyée sur l'API d'auto-complétion
|
||||
# et récupère les aliases de note valides
|
||||
widgets = {
|
||||
'source':
|
||||
autocomplete.ModelSelect2(
|
||||
url='note:note_autocomplete',
|
||||
attrs={
|
||||
'data-placeholder': 'Note ...',
|
||||
'data-minimum-input-length': 1,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -209,6 +209,10 @@ class Alias(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("alias")
|
||||
verbose_name_plural = _("aliases")
|
||||
indexes = [
|
||||
models.Index(fields=['name']),
|
||||
models.Index(fields=['normalized_name']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -119,6 +119,11 @@ class Transaction(PolymorphicModel):
|
||||
class Meta:
|
||||
verbose_name = _("transaction")
|
||||
verbose_name_plural = _("transactions")
|
||||
indexes = [
|
||||
models.Index(fields=['created_at']),
|
||||
models.Index(fields=['source']),
|
||||
models.Index(fields=['destination']),
|
||||
]
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
|
@ -7,9 +7,11 @@ from django.db.models import Q
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import CreateView, ListView, UpdateView
|
||||
from django_tables2 import SingleTableView
|
||||
|
||||
from .forms import TransactionForm, TransactionTemplateForm, ConsoForm
|
||||
from .models import Transaction, TransactionTemplate, Alias, TemplateTransaction
|
||||
from .forms import TransactionForm, TransactionTemplateForm
|
||||
from .models import Transaction, TransactionTemplate, Alias
|
||||
from .tables import HistoryTable
|
||||
|
||||
|
||||
class TransactionCreate(LoginRequiredMixin, CreateView):
|
||||
@ -121,13 +123,16 @@ class TransactionTemplateUpdateView(LoginRequiredMixin, UpdateView):
|
||||
form_class = TransactionTemplateForm
|
||||
|
||||
|
||||
class ConsoView(LoginRequiredMixin, CreateView):
|
||||
class ConsoView(LoginRequiredMixin, SingleTableView):
|
||||
"""
|
||||
Consume
|
||||
"""
|
||||
model = TemplateTransaction
|
||||
model = Transaction
|
||||
template_name = "note/conso_form.html"
|
||||
form_class = ConsoForm
|
||||
|
||||
# Transaction history table
|
||||
table_class = HistoryTable
|
||||
table_pagination = {"per_page": 10}
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""
|
||||
@ -142,9 +147,3 @@ class ConsoView(LoginRequiredMixin, CreateView):
|
||||
context['no_cache'] = True
|
||||
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
"""
|
||||
When clicking a button, reload the same page
|
||||
"""
|
||||
return reverse('note:consos')
|
||||
|
1
apps/scripts
Submodule
1
apps/scripts
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 123466cfa914422422cd372197e64adf65ef05f7
|
@ -1,80 +1,134 @@
|
||||
{% 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">
|
||||
<div class="row">
|
||||
{# User details column #}
|
||||
<div class="col-xl-5">
|
||||
<div class="card border-success shadow mb-4">
|
||||
<img src="https://perso.crans.org/erdnaxe/site-crans/img/logo.svg"
|
||||
alt="" class="img-fluid rounded mx-auto d-block">
|
||||
<div class="card-body text-center">
|
||||
Paquito (aka. PAC) : -230 €
|
||||
</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">
|
||||
<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">
|
||||
<li class="list-group-item py-1 d-flex justify-content-between align-items-center">
|
||||
Cras justo odio
|
||||
<span class="badge badge-dark badge-pill">14</span>
|
||||
</li>
|
||||
<li class="list-group-item py-1 d-flex justify-content-between align-items-center">
|
||||
Dapibus ac facilisis in
|
||||
<span class="badge badge-dark badge-pill">1</span>
|
||||
</li>
|
||||
</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">
|
||||
TODO: reimplement select2 here in JS
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{# 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 template_type as template_types %}
|
||||
|
||||
<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 template_type in template_types %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link font-weight-bold" data-toggle="tab" href="#{{ template_type.grouper|slugify }}">
|
||||
{{ template_type.grouper }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{# Tabs content #}
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
{% for template_type in template_types %}
|
||||
<div class="tab-pane" id="{{ template_type.grouper|slugify }}">
|
||||
<div class="d-inline-flex flex-wrap justify-content-center">
|
||||
{% for button in template_type.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>
|
||||
</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">
|
||||
<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>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrajavascript %}
|
||||
|
Loading…
Reference in New Issue
Block a user