You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

158 lines
5.4 KiB

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, 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:
# We don't have ldap_user on creation, so just add the account
account = Account(user=instance)
account.save()
else:
# 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):
self.credit += amount
self.save()
transaction = Transaction(account=self, subject=subject,
amount=amount, description=desc)
transaction.save()
def buy_products(self, products):
# TODO place it somewhere else
MAX_DEBIT = -35
BUY_SUBJECT = ugettext_noop('Purchase')
if min(products.values()) <= 0:
raise ValueError('Non-positive amount in products dict.')
total_value = sum(map(lambda p: p.price * products[p], products.keys()))
if self.credit - total_value >= MAX_DEBIT:
desc = ''
for product in products.keys():
if not product.active:
raise ValueError('Trying to buy a disabled product.')
amount = products[product]
logentry = SalesLogEntry(account=self, product=product,
count=amount, unit_price=product.price)
logentry.save()
desc += '%d x %s\n' % (amount, product.name)
self.change_credit(-total_value, BUY_SUBJECT, desc)
return True
else:
return False
def buy_product(self, product, amount=1):
return self.buy_products({product: amount})
class ProductCategory(models.Model):
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,
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,
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, 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, 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)
)