diff --git a/docker/dev.sh b/docker/dev.sh index ff4cd047..9802323b 100755 --- a/docker/dev.sh +++ b/docker/dev.sh @@ -20,7 +20,7 @@ docker inspect --type=image asylum_dev >/dev/null 2>&1 if [ "$?" != "0" ] then set -e - docker build -t . + docker build -t asylum_dev . fi set -e echo "Starting devel server." diff --git a/project/members/admin.py b/project/members/admin.py index 602c2f62..66d04def 100644 --- a/project/members/admin.py +++ b/project/members/admin.py @@ -6,10 +6,12 @@ from django import forms from django.contrib import admin from django.db import models +from django.utils import timezone from django.utils.functional import allow_lazy, lazy from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ from reversion.admin import VersionAdmin +from django.db.models import Case, Value, When, DecimalField from .models import Member, MemberNote, MembershipApplication, MembershipApplicationTag, MemberType @@ -104,17 +106,38 @@ def queryset(self, request, queryset): return queryset.filter(credit_annotated__gt=0) +class CreditCurrentYearListFilter(admin.SimpleListFilter): + title = _("Credit %d") % timezone.now().year + parameter_name = 'credit_current_year' + + def lookups(self, request, model_admin): + return ( + (-1, _("Negative credit")), + (1, _("Positive credit")), + ) + + def queryset(self, request, queryset): + v = self.value() + if not v: + return queryset + queryset = queryset.annotate(credit_annotated_current_year=models.Sum(Case(When(creditor_transactions__stamp__year=timezone.now().year, then='creditor_transactions__amount'), output_field=DecimalField()))) + if int(v) < 0: + return queryset.filter(credit_annotated_current_year__lt=0) + return queryset.filter(credit_annotated_current_year__gt=0) + + class MemberAdmin(VersionAdmin): list_display = ( 'rname', 'email', 'nick', 'credit_formatted', + 'credit_formatted_current_year', 'mtypes_formatted', 'grants_formatted', 'city', ) - list_filter = (MemberTypeListFilter, GrantListFilter, CreditListFilter, CityListFilter) + list_filter = (MemberTypeListFilter, GrantListFilter, CreditListFilter, CreditCurrentYearListFilter, CityListFilter) inlines = [MemberNoteInline, GrantInline, TokenInline, RTInline] search_fields = ['lname', 'fname', 'email', 'nick'] ordering = ['lname', 'fname'] @@ -136,6 +159,18 @@ def credit_formatted(self, obj): credit_formatted.short_description = _("Credit") credit_formatted.admin_order_field = 'credit_annotated' + def credit_formatted_current_year(self, obj): + if obj.credit_annotated_current_year is not None: + credit = obj.credit_annotated_current_year + else: + credit = 0.0 + color = "green" + if credit < 0: + color = "red" + return format_html("{}", color, "%+.02f" % credit) + credit_formatted_current_year.short_description = _("Credit %d") % timezone.now().year + credit_formatted_current_year.admin_order_field = 'credit_annotated_current_year' + def mtypes_formatted(self, obj): return ', '.join((x.label for x in obj.mtypes.all())) mtypes_formatted.short_description = _("Membership types") @@ -146,7 +181,8 @@ def grants_formatted(self, obj): def get_queryset(self, request): qs = super().get_queryset(request) - qs = qs.annotate(credit_annotated=models.Sum('creditor_transactions__amount')) + qs = qs.annotate(credit_annotated=models.Sum('creditor_transactions__amount'), + credit_annotated_current_year=models.Sum(Case(When(creditor_transactions__stamp__year=timezone.now().year, then='creditor_transactions__amount'), output_field=DecimalField()))) return qs diff --git a/project/members/locale/fi/LC_MESSAGES/django.po b/project/members/locale/fi/LC_MESSAGES/django.po index c2791bd1..3d8053f2 100644 --- a/project/members/locale/fi/LC_MESSAGES/django.po +++ b/project/members/locale/fi/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-04-04 19:51+0300\n" +"POT-Creation-Date: 2017-08-27 20:18+0300\n" "PO-Revision-Date: 2015-11-29 02:53+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -15,43 +15,48 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 1.8.6\n" -#: admin.py:44 admin.py:142 admin.py:174 models.py:83 +#: admin.py:46 admin.py:176 admin.py:209 models.py:84 msgid "Membership types" msgstr "Jäsentyyppi" -#: admin.py:58 admin.py:146 +#: admin.py:60 admin.py:180 msgid "Grants" msgstr "Pääsyoikeudet" -#: admin.py:72 +#: admin.py:74 msgid "Cities" msgstr "Kaupungit" -#: admin.py:88 admin.py:137 +#: admin.py:89 admin.py:159 msgid "Credit" msgstr "Saldo" -#: admin.py:93 +#: admin.py:94 admin.py:115 msgid "Negative credit" msgstr "Saldo miinuksella" -#: admin.py:94 +#: admin.py:95 admin.py:116 msgid "Positive credit" msgstr "Saldo plussalla" -#: admin.py:125 +#: admin.py:110 admin.py:171 +#, python-format +msgid "Credit %d" +msgstr "Saldo %d" + +#: admin.py:147 msgid "Name" msgstr "Nimi" -#: admin.py:155 admin.py:193 +#: admin.py:190 admin.py:228 msgid "Tags" msgstr "Tägit" -#: admin.py:202 +#: admin.py:237 msgid "Approve selected applications" msgstr "Hyväksy valitut hakemukset" -#: forms.py:18 +#: forms.py:19 #, python-format msgid "I have read and accept the rules" msgstr "Olen lukenut ja hyväksyn säännöt" @@ -80,7 +85,7 @@ msgstr "Puhelinnumero" msgid "Nickname" msgstr "Lempinimi" -#: models.py:69 models.py:106 +#: models.py:69 models.py:108 msgid "Label" msgstr "Nimiö" @@ -92,63 +97,63 @@ msgstr "Jäsentyyppi" msgid "Member Types" msgstr "Jäsentyypit" -#: models.py:82 +#: models.py:83 msgid "Date accepted" msgstr "Hyväksymispäivä" -#: models.py:84 +#: models.py:85 msgid "Anonymized id (for use in external databases)" msgstr "Anonymisoitu tunniste (käytettäväksi ulkoisissa tietokannoissa)" -#: models.py:85 +#: models.py:86 msgid "Member id no" msgstr "Jäsennumero" -#: models.py:99 models.py:170 +#: models.py:100 models.py:174 msgid "Member" msgstr "Jäsen" -#: models.py:100 +#: models.py:101 msgid "Members" msgstr "Jäsenet" -#: models.py:112 +#: models.py:114 msgid "Membership Application Tag" msgstr "Jäsenhakemuksen tägi" -#: models.py:113 +#: models.py:115 msgid "Membership Application Tags" msgstr "Jäsenhakemuksen tägit" -#: models.py:120 +#: models.py:123 msgid "Application tags" msgstr "Jäsenhakemuksen tagit" -#: models.py:121 models.py:169 models.py:174 +#: models.py:124 models.py:173 models.py:178 msgid "Notes" msgstr "Muistiinpanot" -#: models.py:132 +#: models.py:135 msgid "Member with this email already exists" msgstr "Tämä sähköpostiosoite on jo jäsenrekisterissä" -#: models.py:161 +#: models.py:164 msgid "Membership Application" msgstr "Jäsenhakemus" -#: models.py:162 +#: models.py:165 msgid "Membership Applications" msgstr "Jäsenhakemukset" -#: models.py:168 +#: models.py:172 msgid "Datetime" msgstr "Päivä ja aika" -#: models.py:173 +#: models.py:177 msgid "Note" msgstr "Muistiinpano" -#: models.py:178 +#: models.py:182 #, python-format msgid "Notes about %s on %s" msgstr "Muistiinpanoja jäsenestä %s ajalla %s"