Files
@ 4069d4bb3208
Branch filter:
Location: symposion_app/registrasion/controllers/invoice.py - annotation
4069d4bb3208
4.4 KiB
text/x-python
Merge branch 'guided_registration'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | d9e433659d01 d9e433659d01 224878a10ce3 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 224878a10ce3 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 224878a10ce3 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 a4de15830c18 a4de15830c18 a4de15830c18 d9e433659d01 d9e433659d01 d9e433659d01 a4de15830c18 d9e433659d01 d9e433659d01 a4de15830c18 d9e433659d01 a4de15830c18 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 224878a10ce3 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 83b11cd7224d d9e433659d01 d9e433659d01 d9e433659d01 224878a10ce3 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 | from decimal import Decimal
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Sum
from registrasion import models as rego
from cart import CartController
class InvoiceController(object):
def __init__(self, invoice):
self.invoice = invoice
@classmethod
def for_cart(cls, cart):
''' Returns an invoice object for a given cart at its current revision.
If such an invoice does not exist, the cart is validated, and if valid,
an invoice is generated.'''
try:
invoice = rego.Invoice.objects.get(
cart=cart, cart_revision=cart.revision)
except ObjectDoesNotExist:
cart_controller = CartController(cart)
cart_controller.validate_cart() # Raises ValidationError on fail.
invoice = cls._generate(cart)
return InvoiceController(invoice)
@classmethod
def resolve_discount_value(cls, item):
try:
condition = rego.DiscountForProduct.objects.get(
discount=item.discount,
product=item.product
)
except ObjectDoesNotExist:
condition = rego.DiscountForCategory.objects.get(
discount=item.discount,
category=item.product.category
)
if condition.percentage is not None:
value = item.product.price * (condition.percentage / 100)
else:
value = condition.price
return value
@classmethod
def _generate(cls, cart):
''' Generates an invoice for the given cart. '''
invoice = rego.Invoice.objects.create(
user=cart.user,
cart=cart,
cart_revision=cart.revision,
value=Decimal()
)
invoice.save()
# TODO: calculate line items.
product_items = rego.ProductItem.objects.filter(cart=cart)
product_items = product_items.order_by(
"product__category__order", "product__order"
)
discount_items = rego.DiscountItem.objects.filter(cart=cart)
invoice_value = Decimal()
for item in product_items:
product = item.product
line_item = rego.LineItem.objects.create(
invoice=invoice,
description="%s - %s" % (product.category.name, product.name),
quantity=item.quantity,
price=product.price,
)
line_item.save()
invoice_value += line_item.quantity * line_item.price
for item in discount_items:
line_item = rego.LineItem.objects.create(
invoice=invoice,
description=item.discount.description,
quantity=item.quantity,
price=cls.resolve_discount_value(item) * -1,
)
line_item.save()
invoice_value += line_item.quantity * line_item.price
# TODO: calculate line items from discounts
invoice.value = invoice_value
invoice.save()
return invoice
def is_valid(self):
''' Returns true if the attached invoice is not void and it represents
a valid cart. '''
if self.invoice.void:
return False
if self.invoice.cart is not None:
if self.invoice.cart.revision != self.invoice.cart_revision:
return False
return True
def void(self):
''' Voids the invoice. '''
self.invoice.void = True
def pay(self, reference, amount):
''' Pays the invoice by the given amount. If the payment
equals the total on the invoice, finalise the invoice.
(NB should be transactional.)
'''
if self.invoice.cart is not None:
cart = CartController(self.invoice.cart)
cart.validate_cart() # Raises ValidationError if invalid
''' Adds a payment '''
payment = rego.Payment.objects.create(
invoice=self.invoice,
reference=reference,
amount=amount,
)
payment.save()
payments = rego.Payment.objects.filter(invoice=self.invoice)
agg = payments.aggregate(Sum("amount"))
total = agg["amount__sum"]
if total == self.invoice.value:
self.invoice.paid = True
cart = self.invoice.cart
cart.active = False
cart.save()
self.invoice.save()
|