Browse Source

Prepared model, view and admin for i18n and included German translation file; added pre-delete handler for purchase cancellation

master
Niklas Brachmann 11 years ago
parent
commit
7e6cedbb9d
  1. 18
      cash/admin.py
  2. 160
      cash/locale/de/LC_MESSAGES/django.po
  3. 109
      cash/models.py
  4. 3
      cash/views.py
  5. 1
      lugcash2/settings.py

18
cash/admin.py

@ -3,9 +3,12 @@ from cash.models import * @@ -3,9 +3,12 @@ from cash.models import *
from django import forms
from django.template.defaultfilters import escape
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy
from django.utils.translation import ugettext_noop
class AccountForm(forms.ModelForm):
credit_change = forms.DecimalField(max_digits = 5, decimal_places = 2, required = False)
credit_change = forms.DecimalField(max_digits = 5, decimal_places = 2, required = False, label = ugettext_lazy('change change'))
class Meta:
model = Account
@ -16,15 +19,16 @@ class AccountAdmin(admin.ModelAdmin): @@ -16,15 +19,16 @@ class AccountAdmin(admin.ModelAdmin):
readonly_fields = ('credit',)
def transaction_link(self, account):
return '<a href="%s?account__id__exact=%d">Transaktionen</a>' % (reverse("admin:cash_transaction_changelist"), account.id)
return '<a href="%s?account__id__exact=%d">%s</a>' % (reverse("admin:cash_transaction_changelist"), account.id, _('Transactions'))
transaction_link.short_description = ugettext_lazy('Transaction link')
transaction_link.allow_tags = True
def save_model(self, request, obj, form, change):
# TODO: Auslagern
PAYOUT_SUBJECT = "Auszahlung"
DEPOSIT_SUBJECT = "Einzahlung"
DESC = "Autorisiert von %s %s"
PAYOUT_SUBJECT = ugettext_noop('Payout')
DEPOSIT_SUBJECT = ugettext_noop('Deposit')
DESC = ugettext_noop('Authorized by %(first)s %(last)s')
amount = form.cleaned_data['credit_change']
@ -80,7 +84,7 @@ class TransactionAdmin(admin.ModelAdmin): @@ -80,7 +84,7 @@ class TransactionAdmin(admin.ModelAdmin):
admin.site.register(Account, AccountAdmin)
admin.site.register(Product, ProductAdmin)
admin.site.register(ProductBarcode)
#admin.site.register(ProductBarcode)
admin.site.register(ProductCategory, ProductCategoryAdmin)
admin.site.register(Transaction, TransactionAdmin)
admin.site.register(SalesLogEntry, SalesLogEntryAdmin)

160
cash/locale/de/LC_MESSAGES/django.po

@ -0,0 +1,160 @@ @@ -0,0 +1,160 @@
# German language file for django cash app.
# Copyright (C) 2013 Niklas Brachmann
# This file is distributed under the same license as the cash package.
# Niklas Brachmann <mail@klonfish.de>, 2013.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-09-13 01:46+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: admin.py:11
msgid "change change"
msgstr "Ein-/Auszahlung"
#: admin.py:22
msgid "Transactions"
msgstr "Transaktionen"
#: admin.py:24
msgid "Transaction link"
msgstr "Transaktionslink"
#: admin.py:29
msgid "Payout"
msgstr "Auszahlung"
#: admin.py:30
msgid "Deposit"
msgstr "Einzahlung"
#: admin.py:31
#, python-format
msgid "Authorized by %(first)s %(last)s"
msgstr "Autorisiert von %(first)s %(last)s"
#: models.py:13
msgid "card number"
msgstr "Kartennummer"
#: models.py:14
msgid "PIN"
msgstr "PIN"
#: models.py:15
msgid "daily digest"
msgstr "Tägliche Zusammenfassung"
#: models.py:17
msgid "credit"
msgstr "Guthaben"
#: models.py:23 models.py:124 models.py:137
msgid "account"
msgstr "Konto"
#: models.py:24
msgid "accounts"
msgstr "Konten"
#: models.py:52
msgid "Purchase"
msgstr "Einkauf"
#: models.py:82 models.py:95
msgid "name"
msgstr "Name"
#: models.py:84 models.py:113
msgid "comment"
msgstr "Kommentar"
#: models.py:90
msgid "product category"
msgstr "Produktkategorie"
#: models.py:91
msgid "product categories"
msgstr "Produktkategorien"
#: models.py:97
msgid "price"
msgstr "Preis"
#: models.py:98
msgid "active"
msgstr "Aktiv"
#: models.py:100
msgid "category"
msgstr "Kategorie"
#: models.py:106 models.py:107 models.py:114 models.py:138
msgid "product"
msgstr "Produkt"
#: models.py:111 models.py:120
msgid "barcode"
msgstr "Strichcode"
#: models.py:121
msgid "barcodes"
msgstr "Strichcodes"
#: models.py:126 models.py:143
msgid "timestamp"
msgstr "Zeitstempel"
#: models.py:127
msgid "subject"
msgstr "Betreff"
#: models.py:128
msgid "description"
msgstr "Beschreibung"
#: models.py:130
msgid "amount"
msgstr "Betrag"
#: models.py:133
msgid "transaction"
msgstr "Transaktion"
#: models.py:134
msgid "transactions"
msgstr "Transaktionen"
#: models.py:139
msgid "count"
msgstr "Anzahl"
#: models.py:141
msgid "unit price"
msgstr "Stückpreis"
#: models.py:146
msgid "sales log entry"
msgstr "Verkaufsprotokolleintrag"
#: models.py:147
msgid "sales log entries"
msgstr "Verkaufsprotokolleinträge"
#: models.py:152
msgid "Cancellation"
msgstr "Stornierung"
#: views.py:84
msgid "PINs do not match."
msgstr "PINs stimmen nicht überein."

109
cash/models.py

@ -1,20 +1,28 @@ @@ -1,20 +1,28 @@
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.db.models.signals import pre_delete
from django.dispatch import receiver
from django_auth_ldap.backend import populate_user
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext_noop
class Account(models.Model):
user = models.OneToOneField(User)
card_number = models.CharField(max_length=32, unique=True, blank=True,
null=True)
pin = models.CharField(max_length=32, blank=True)
daily_digest = models.BooleanField()
credit = models.DecimalField(max_digits=5, decimal_places=2, default=0)
null=True, verbose_name = _('card number'))
pin = models.CharField(max_length=32, blank=True, verbose_name = _('PIN'))
daily_digest = models.BooleanField(verbose_name = _('daily digest'))
credit = models.DecimalField(max_digits=5, decimal_places=2, default=0,
verbose_name = _('credit'))
def __unicode__(self):
return self.user.username
class Meta:
verbose_name = _('account')
verbose_name_plural = _('accounts')
@receiver(post_save, sender=User)
def user_post_save_handler(sender, instance, created, **kwargs):
if created:
@ -22,9 +30,12 @@ class Account(models.Model): @@ -22,9 +30,12 @@ class Account(models.Model):
account = Account(user=instance)
account.save()
else:
# When we alraedy have an account, we can add the number form LDAP (mongo shit)
if hasattr(instance, 'ldap_user') and instance.ldap_user.attrs.has_key('employeenumber'):
instance.account.card_number = instance.ldap_user.attrs['employeenumber'][0]
# When we already have an account,
# we can add the number form LDAP (mongo shit)
if hasattr(instance, 'ldap_user') \
and instance.ldap_user.attrs.has_key('employeenumber'):
instance.account.card_number = \
instance.ldap_user.attrs['employeenumber'][0]
instance.account.save()
def change_credit(self, amount, subject, desc):
@ -38,7 +49,7 @@ class Account(models.Model): @@ -38,7 +49,7 @@ class Account(models.Model):
def buy_products(self, products):
# TODO place it somewhere else
MAX_DEBIT = -35
BUY_SUBJECT = 'Artikel gekauft'
BUY_SUBJECT = ugettext_noop('Purchase')
if min(products.values()) <= 0:
raise ValueError('Non-positive amount in products dict.')
@ -55,7 +66,7 @@ class Account(models.Model): @@ -55,7 +66,7 @@ class Account(models.Model):
count=amount, unit_price=product.price)
logentry.save()
desc += '%dx %s\n' % (amount, product.name)
desc += '%d x %s\n' % (amount, product.name)
self.change_credit(-total_value, BUY_SUBJECT, desc)
return True
@ -67,42 +78,78 @@ class Account(models.Model): @@ -67,42 +78,78 @@ class Account(models.Model):
class ProductCategory(models.Model):
name = models.CharField(max_length=32, unique=True)
comment = models.CharField(max_length=128, blank=True)
name = models.CharField(max_length=32, unique=True,
verbose_name = _('name'))
comment = models.CharField(max_length=128, blank=True,
verbose_name = _('comment'))
def __unicode__(self):
return "%s (%s)" % (self.name, self.comment)
class Meta:
verbose_name = _('product category')
verbose_name_plural = _('product categories')
class Product(models.Model):
name = models.CharField(max_length=32, unique=True)
price = models.DecimalField(max_digits=5, decimal_places=2)
active = models.BooleanField(default = True)
category = models.ForeignKey(ProductCategory, blank=True, null=True)
name = models.CharField(max_length=32, unique=True,
verbose_name = _('name'))
price = models.DecimalField(max_digits=5, decimal_places=2,
verbose_name = _('price'))
active = models.BooleanField(default = True, verbose_name = _('active'))
category = models.ForeignKey(ProductCategory, blank=True, null=True,
verbose_name = _('category'))
def __unicode__(self):
return self.name
class Meta:
verbose_name = _('product')
verbose_name_plural = _('product')
class ProductBarcode(models.Model):
barcode = models.CharField(max_length=32, unique=True)
comment = models.CharField(max_length=128, blank=True)
product = models.ForeignKey(Product)
barcode = models.CharField(max_length=32, unique=True,
verbose_name = _('barcode'))
comment = models.CharField(max_length=128, blank=True,
verbose_name = _('comment'))
product = models.ForeignKey(Product, verbose_name = _('product'))
def __unicode__(self):
return self.barcode
class Meta:
verbose_name = _('barcode')
verbose_name_plural = _('barcodes')
class Transaction(models.Model):
account = models.ForeignKey(Account)
timestamp = models.DateTimeField(auto_now_add=True)
subject = models.CharField(max_length=32)
description = models.TextField()
amount = models.DecimalField(max_digits=5, decimal_places=2)
account = models.ForeignKey(Account, verbose_name = _('account'))
timestamp = models.DateTimeField(auto_now_add=True,
verbose_name = _('timestamp'))
subject = models.CharField(max_length=32, verbose_name = _('subject'))
description = models.TextField(verbose_name = _('description'))
amount = models.DecimalField(max_digits=5, decimal_places=2,
verbose_name = _('amount'))
class Meta:
verbose_name = _('transaction')
verbose_name_plural = _('transactions')
class SalesLogEntry(models.Model):
account = models.ForeignKey(Account)
product = models.ForeignKey(Product)
count = models.IntegerField()
unit_price = models.DecimalField(max_digits=5, decimal_places=2)
timestamp = models.DateTimeField(auto_now_add=True)
account = models.ForeignKey(Account, verbose_name = _('account'))
product = models.ForeignKey(Product, verbose_name = _('product'))
count = models.IntegerField(verbose_name = _('count'))
unit_price = models.DecimalField(max_digits=5, decimal_places=2,
verbose_name = _('unit price'))
timestamp = models.DateTimeField(auto_now_add=True,
verbose_name = _('timestamp'))
class Meta:
verbose_name = _('sales log entry')
verbose_name_plural = _('sales log entries')
@receiver(pre_delete, sender=SalesLogEntry)
def logentry_pre_delete_handler(sender, instance, **kwargs):
SUBJECT = ugettext_noop('Cancellation')
DESC = '%d x %s'
instance.account.change_credit(instance.unit_price * instance.count, SUBJECT, DESC % (instance.count, instance.product.name))

3
cash/views.py

@ -5,6 +5,7 @@ from django.contrib.auth.decorators import login_required @@ -5,6 +5,7 @@ from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from django.core import paginator
from cash.models import *
from django.utils.translation import ugettext as _
@login_required
def overview(request):
@ -80,7 +81,7 @@ class UserPinForm(forms.Form): @@ -80,7 +81,7 @@ class UserPinForm(forms.Form):
cleaned_data = super(UserPinForm, self).clean()
if cleaned_data['pin'] != cleaned_data['pin_confirm']:
raise forms.ValidationError('Pins sind ungleich.')
raise forms.ValidationError(_('PINs do not match.'))
return cleaned_data

1
lugcash2/settings.py

@ -101,6 +101,7 @@ MIDDLEWARE_CLASSES = ( @@ -101,6 +101,7 @@ MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.locale.LocaleMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

Loading…
Cancel
Save