commit initial customorder support
This commit is contained in:
parent
5e151da366
commit
3ce6b70e99
|
@ -4,7 +4,7 @@ from django.conf import settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from shop.pdf import generate_pdf_letter
|
from shop.pdf import generate_pdf_letter
|
||||||
from shop.email import send_invoice_email, send_creditnote_email
|
from shop.email import send_invoice_email, send_creditnote_email
|
||||||
from shop.models import Order, Invoice, CreditNote
|
from shop.models import Order, CustomOrder, Invoice, CreditNote
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
@ -19,11 +19,17 @@ class Command(BaseCommand):
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
self.output('Invoice worker running...')
|
self.output('Invoice worker running...')
|
||||||
while True:
|
while True:
|
||||||
# check if we need to generate any invoices
|
# check if we need to generate any invoices for shop orders
|
||||||
for order in Order.objects.filter(paid=True, invoice__isnull=True):
|
for order in Order.objects.filter(paid=True, invoice__isnull=True):
|
||||||
# generate invoice for this Order
|
# generate invoice for this Order
|
||||||
Invoice.objects.create(order=order)
|
Invoice.objects.create(order=order)
|
||||||
self.output('Generated Invoice object for order %s' % order)
|
self.output('Generated Invoice object for %s' % order)
|
||||||
|
|
||||||
|
# check if we need to generate any invoices for custom orders
|
||||||
|
for customorder in CustomOrder.objects.filter(paid=True, invoice__isnull=True):
|
||||||
|
# generate invoice for this CustomOrder
|
||||||
|
Invoice.objects.create(customorder=customorder)
|
||||||
|
self.output('Generated Invoice object for %s' % customorder)
|
||||||
|
|
||||||
# check if we need to generate any pdf invoices
|
# check if we need to generate any pdf invoices
|
||||||
for invoice in Invoice.objects.filter(pdf=''):
|
for invoice in Invoice.objects.filter(pdf=''):
|
||||||
|
@ -34,9 +40,13 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
# generate the pdf
|
# generate the pdf
|
||||||
try:
|
try:
|
||||||
|
if invoice.customorder:
|
||||||
|
template='pdf/custominvoice.html'
|
||||||
|
else:
|
||||||
|
template='pdf/invoice.html'
|
||||||
pdffile = generate_pdf_letter(
|
pdffile = generate_pdf_letter(
|
||||||
filename=invoice.filename,
|
filename=invoice.filename,
|
||||||
template='pdf/invoice.html',
|
template=template,
|
||||||
formatdict=formatdict,
|
formatdict=formatdict,
|
||||||
)
|
)
|
||||||
self.output('Generated pdf for invoice %s' % invoice)
|
self.output('Generated pdf for invoice %s' % invoice)
|
||||||
|
@ -54,8 +64,8 @@ class Command(BaseCommand):
|
||||||
invoice.save()
|
invoice.save()
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
# check if we need to send out any invoices (only where pdf has been generated)
|
# check if we need to send out any invoices (only for shop orders, and only where pdf has been generated)
|
||||||
for invoice in Invoice.objects.filter(sent_to_customer=False).exclude(pdf=''):
|
for invoice in Invoice.objects.filter(order__isnull=False, sent_to_customer=False).exclude(pdf=''):
|
||||||
# send the email
|
# send the email
|
||||||
if send_invoice_email(invoice=invoice):
|
if send_invoice_email(invoice=invoice):
|
||||||
self.output('OK: Invoice email sent to %s' % invoice.order.user.email)
|
self.output('OK: Invoice email sent to %s' % invoice.order.user.email)
|
||||||
|
|
|
@ -15,8 +15,34 @@ from decimal import Decimal
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
|
|
||||||
class Order(CreatedUpdatedModel):
|
class CustomOrder(CreatedUpdatedModel):
|
||||||
|
camp = models.ForeignKey(
|
||||||
|
'camps.Camp',
|
||||||
|
verbose_name=_('Camp'),
|
||||||
|
help_text=_('The camp this custom order is for.'),
|
||||||
|
)
|
||||||
|
|
||||||
|
text = models.TextField()
|
||||||
|
|
||||||
|
amount = models.IntegerField(
|
||||||
|
help_text=_('Amount of this custom order (in DKK, including VAT).')
|
||||||
|
)
|
||||||
|
|
||||||
|
paid = models.BooleanField(
|
||||||
|
verbose_name=_('Paid?'),
|
||||||
|
help_text=_('Whether this custom order has been paid.'),
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'custom order id #%s' % self.pk
|
||||||
|
|
||||||
|
@property
|
||||||
|
def vat(self):
|
||||||
|
return Decimal(self.amount*Decimal(0.2))
|
||||||
|
|
||||||
|
|
||||||
|
class Order(CreatedUpdatedModel):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('user', 'open')
|
unique_together = ('user', 'open')
|
||||||
ordering = ['-created']
|
ordering = ['-created']
|
||||||
|
@ -29,26 +55,26 @@ class Order(CreatedUpdatedModel):
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
'auth.User',
|
'auth.User',
|
||||||
verbose_name=_('User'),
|
verbose_name=_('User'),
|
||||||
help_text=_('The user this order belongs to.'),
|
help_text=_('The user this shop order belongs to.'),
|
||||||
related_name='orders',
|
related_name='orders',
|
||||||
)
|
)
|
||||||
|
|
||||||
paid = models.BooleanField(
|
paid = models.BooleanField(
|
||||||
verbose_name=_('Paid?'),
|
verbose_name=_('Paid?'),
|
||||||
help_text=_('Whether this order has been paid.'),
|
help_text=_('Whether this shop order has been paid.'),
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
open = models.NullBooleanField(
|
open = models.NullBooleanField(
|
||||||
verbose_name=_('Open?'),
|
verbose_name=_('Open?'),
|
||||||
help_text=_('Whether this order is open or not. "None" means closed.'),
|
help_text=_('Whether this shop order is open or not. "None" means closed.'),
|
||||||
default=True,
|
default=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
camp = models.ForeignKey(
|
camp = models.ForeignKey(
|
||||||
'camps.Camp',
|
'camps.Camp',
|
||||||
verbose_name=_('Camp'),
|
verbose_name=_('Camp'),
|
||||||
help_text=_('The camp this order is for.'),
|
help_text=_('The camp this shop order is for.'),
|
||||||
)
|
)
|
||||||
|
|
||||||
CREDIT_CARD = 'credit_card'
|
CREDIT_CARD = 'credit_card'
|
||||||
|
@ -84,7 +110,7 @@ class Order(CreatedUpdatedModel):
|
||||||
objects = OrderQuerySet.as_manager()
|
objects = OrderQuerySet.as_manager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'order id #%s' % self.pk
|
return 'shop order id #%s' % self.pk
|
||||||
|
|
||||||
def get_number_of_items(self):
|
def get_number_of_items(self):
|
||||||
return self.products.aggregate(
|
return self.products.aggregate(
|
||||||
|
@ -225,7 +251,7 @@ class Product(CreatedUpdatedModel, UUIDModel):
|
||||||
slug = models.SlugField()
|
slug = models.SlugField()
|
||||||
|
|
||||||
price = models.IntegerField(
|
price = models.IntegerField(
|
||||||
help_text=_('Price of the product (in DKK).')
|
help_text=_('Price of the product (in DKK, including VAT).')
|
||||||
)
|
)
|
||||||
|
|
||||||
description = models.TextField()
|
description = models.TextField()
|
||||||
|
@ -326,19 +352,29 @@ class CreditNote(CreatedUpdatedModel):
|
||||||
|
|
||||||
|
|
||||||
class Invoice(CreatedUpdatedModel):
|
class Invoice(CreatedUpdatedModel):
|
||||||
order = models.OneToOneField('shop.Order')
|
order = models.OneToOneField('shop.Order', null=True, blank=True)
|
||||||
|
customorder = models.OneToOneField('shop.CustomOrder', null=True, blank=True)
|
||||||
pdf = models.FileField(null=True, blank=True, upload_to='invoices/')
|
pdf = models.FileField(null=True, blank=True, upload_to='invoices/')
|
||||||
sent_to_customer = models.BooleanField(default=False)
|
sent_to_customer = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'invoice#%s - order %s - %s - total %s DKK (sent to %s: %s)' % (
|
if self.order:
|
||||||
self.id,
|
return 'invoice#%s - shop order %s - %s - total %s DKK (sent to %s: %s)' % (
|
||||||
self.order.id,
|
self.id,
|
||||||
self.order.created,
|
self.order.id,
|
||||||
self.order.total,
|
self.order.created,
|
||||||
self.order.user.email,
|
self.order.total,
|
||||||
self.sent_to_customer,
|
self.order.user.email,
|
||||||
)
|
self.sent_to_customer,
|
||||||
|
)
|
||||||
|
elif self.customorder:
|
||||||
|
return 'invoice#%s - custom order %s - %s - amount %s DKK (customer: %s)' % (
|
||||||
|
self.id,
|
||||||
|
self.customorder.id,
|
||||||
|
self.customorder.created,
|
||||||
|
self.customorder.amount,
|
||||||
|
self.customorder.customer,
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def filename(self):
|
def filename(self):
|
||||||
|
|
57
shop/templates/pdf/custominvoice.html
Normal file
57
shop/templates/pdf/custominvoice.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% load static from staticfiles %}
|
||||||
|
{% load shop_tags %}
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
|
||||||
|
<table style="width:100%;">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 75%;"> </td>
|
||||||
|
<td>
|
||||||
|
<h3>
|
||||||
|
{{ invoice.created|date:"b jS, Y" }}<br>
|
||||||
|
Order CU#{{ invoice.customorder.pk }}<br>
|
||||||
|
Invoice #{{ invoice.pk }}
|
||||||
|
</h3>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Customer: {{ invoice.customorder.customer }}</h3>
|
||||||
|
<br>
|
||||||
|
<h2>INVOICE</h2>
|
||||||
|
<table style="width:90%; margin:1em;">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Text
|
||||||
|
<td>
|
||||||
|
<b>Quantity
|
||||||
|
<td>
|
||||||
|
<b>Price
|
||||||
|
<td>
|
||||||
|
<b>Total
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ invoice.customorder.text }}
|
||||||
|
<td>
|
||||||
|
1
|
||||||
|
<td align="right">
|
||||||
|
{{ invoice.customorder.amount|currency }}
|
||||||
|
<td align="right">
|
||||||
|
{{ invoice.customorder.amount|currency }}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<td>
|
||||||
|
<strong>Danish VAT (25%)</strong>
|
||||||
|
<td align="right">
|
||||||
|
{{ invoice.customorder.vat|currency }}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<td>
|
||||||
|
<strong>Total</strong>
|
||||||
|
<td align="right">
|
||||||
|
{{ invoice.customorder.amount|currency }}
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<p class="lead">
|
||||||
|
Payment should be made by bank transfer to Arbejdernes Landsbank reg. 5371 account no. 0244504 within two weeks from {{ invoice.created|date:"b jS, Y" }} please. Thank you!
|
||||||
|
</p>
|
Loading…
Reference in a new issue