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.
 
 
 
 
 

119 lines
3.9 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
from django.conf import settings
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.debit_limit is not None:
debit_limit = self.account.debit_limit
else:
debit_limit = settings.CASHONLY_DEFAULT_DEBIT_LIMIT
if self.account.credit - total_value >= 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)