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.
 
 
 
 
 

114 lines
3.7 KiB

from cashonly.core.models import Account, Transaction, SalesLogEntry, Product
from django.core.files import File
from django.contrib.auth.models import User
from django.utils.translation import ugettext_noop
from django.db.models.signals import pre_save, post_save, pre_delete
from django.dispatch import receiver
from django.db import transaction
import PIL.Image
import io
class AccountManager:
def __init__(self, account):
self.account = account
@transaction.atomic
def add_transaction(self, amount, subject, description):
self.account.refresh_from_db()
self.account.credit = self.account.credit + amount
self.account.save()
Transaction.objects.create(account=self.account, subject=subject,
amount=amount, description=description)
def change_credit(self, amount, operator, comment=None):
if amount > 0:
subject = ugettext_noop('Deposit')
elif amount < 0:
subject = ugettext_noop('Payout')
else:
raise ValueError('Amount must not be zero.')
desc = ugettext_noop('Authorized by %(first)s %(last)s') % \
{'first': operator.first_name, 'last': operator.last_name}
if comment is not None and len(comment) > 0:
desc += ' (%s)' % (comment)
self.add_transaction(amount, subject, desc)
@transaction.atomic
def buy_products(self, products):
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.account.credit - total_value >= self.account.debit_limit * -1:
desc = ''
for product in products.keys():
if not product.active:
raise ValueError('Trying to buy a disabled product.')
amount = products[product]
desc += '%d x %s\n' % (amount, product.name)
SalesLogEntry.objects.create(
account=self.account,
product=product,
count=amount,
unit_price=product.price
)
self.add_transaction(-total_value, ugettext_noop('Purchase'), desc)
return True
else:
return False
def buy_product(self, product, amount):
return self.buy_products({product: amount})
def set_pin(self, pin):
self.account.pin = pin
self.account.save()
def clear_pin(self):
self.set_pin('')
def check_pin(self, pin):
return self.account.pin == pin
@receiver(post_save, sender=User)
def user_post_save_handler(sender, instance, created, **kwargs):
# TODO: add possibility to disable this via settings variable
if created:
Account.objects.create(user=instance)
@receiver(pre_delete, sender=SalesLogEntry)
def logentry_pre_delete_handler(sender, instance, **kwargs):
accmgr = AccountManager(instance.account)
accmgr.add_transaction(
instance.unit_price * instance.count,
ugettext_noop('Cancellation'),
'%d x %s' % (instance.count, instance.product.name)
)
@receiver(pre_save, sender=Product)
def product_post_save_handler(sender, instance, **kwargs):
# FIXME
img = instance.image
if img:
scaledFile = io.StringIO()
img.open(mode='r')
with img:
scaled = PIL.Image.open(img)
thumbnail_size = getattr(settings, 'THUMBNAIL_SIZE', (150, 150))
scaled.thumbnail(thumbnail_size, PIL.Image.ANTIALIAS)
scaled.save(scaledFile, 'PNG')
scaledFile.seek(0)
instance.image_thumbnail.save(img.url, File(scaledFile), save=False)