commit creditnote stuff

This commit is contained in:
Thomas Steen Rasmussen 2016-06-18 20:51:53 +02:00
parent da4843bb06
commit c6d4c1edc3
7 changed files with 177 additions and 11 deletions

View file

@ -7,6 +7,7 @@ admin.site.register(models.EpayPayment)
admin.site.register(models.CoinifyAPIInvoice) admin.site.register(models.CoinifyAPIInvoice)
admin.site.register(models.CoinifyAPICallback) admin.site.register(models.CoinifyAPICallback)
admin.site.register(models.Invoice) admin.site.register(models.Invoice)
admin.site.register(models.CreditNote)
@admin.register(models.ProductCategory) @admin.register(models.ProductCategory)
@ -55,12 +56,12 @@ class OrderAdmin(admin.ModelAdmin):
] ]
list_filter = [ list_filter = [
'user',
'camp', 'camp',
'payment_method', 'payment_method',
'open', 'open',
'paid', 'paid',
'cancelled', 'cancelled',
'user',
] ]
exclude = ['products'] exclude = ['products']

View file

@ -11,6 +11,10 @@ def send_email(emailtype, recipient, formatdict, subject, sender='BornHack <info
text_template = 'emails/invoice_email.txt' text_template = 'emails/invoice_email.txt'
html_template = 'emails/invoice_email.html' html_template = 'emails/invoice_email.html'
attachment_filename = formatdict['filename'] attachment_filename = formatdict['filename']
if emailtype == 'creditnote':
text_template = 'emails/creditnote_email.txt'
html_template = 'emails/creditnote_email.html'
attachment_filename = formatdict['creditnote'].filename
elif emailtype == 'testmail': elif emailtype == 'testmail':
text_template = 'emails/testmail.txt' text_template = 'emails/testmail.txt'
else: else:
@ -40,6 +44,24 @@ def send_email(emailtype, recipient, formatdict, subject, sender='BornHack <info
return True return True
def send_creditnote_email(creditnote):
# put formatdict together
formatdict = {
'creditnote': creditnote,
}
subject = 'BornHack creditnote %s' % creditnote.pk
# send mail
return send_email(
emailtype='creditnote',
recipient=creditnote.user.email,
formatdict=formatdict,
subject=subject,
sender='info@bornhack.dk',
attachment=creditnote.pdf.read(),
)
def send_invoice_email(invoice): def send_invoice_email(invoice):
# put formatdict together # put formatdict together
formatdict = { formatdict = {

View file

@ -3,15 +3,15 @@ from django.core.files import File
from django.conf import settings 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 from shop.email import send_invoice_email, send_creditnote_email
from shop.models import Order, Invoice from shop.models import Order, Invoice, CreditNote
from time import sleep from time import sleep
from decimal import Decimal from decimal import Decimal
class Command(BaseCommand): class Command(BaseCommand):
args = 'none' args = 'none'
help = 'Send out invoices that have not been sent yet' help = 'Generate invoices and credit notes, and email invoices that have not been sent yet'
def output(self, message): def output(self, message):
self.stdout.write('%s: %s' % (timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message)) self.stdout.write('%s: %s' % (timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message))
@ -53,6 +53,7 @@ class Command(BaseCommand):
invoice.pdf.save(invoice.filename, File(pdffile)) invoice.pdf.save(invoice.filename, File(pdffile))
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 where pdf has been generated)
for invoice in Invoice.objects.filter(sent_to_customer=False).exclude(pdf=''): for invoice in Invoice.objects.filter(sent_to_customer=False).exclude(pdf=''):
# send the email # send the email
@ -63,6 +64,46 @@ class Command(BaseCommand):
else: else:
self.output('ERROR: Unable to send invoice email for order %s to %s' % (invoice.order.pk, invoice.order.user.email)) self.output('ERROR: Unable to send invoice email for order %s to %s' % (invoice.order.pk, invoice.order.user.email))
###############################################################
# check if we need to generate any pdf creditnotes?
for creditnote in CreditNote.objects.filter(pdf=''):
# put the dict with data for the pdf together
formatdict = {
'creditnote': creditnote,
}
# generate the pdf
try:
pdffile = generate_pdf_letter(
filename=creditnote.filename,
template='pdf/creditnote.html',
formatdict=formatdict,
)
self.output('Generated pdf for creditnote %s' % creditnote)
except Exception as E:
self.output('ERROR: Unable to generate PDF file for creditnote #%s. Error: %s' % (creditnote.pk, E))
continue
# so, do we have a pdf?
if not pdffile:
self.output('ERROR: Unable to generate PDF file for creditnote #%s' % creditnote.pk)
continue
# update creditnote object with the file
creditnote.pdf.save(creditnote.filename, File(pdffile))
creditnote.save()
###############################################################
# check if we need to send out any creditnotes (only where pdf has been generated)
for creditnote in CreditNote.objects.filter(sent_to_customer=False).exclude(pdf=''):
# send the email
if send_creditnote_email(creditnote=creditnote):
self.output('OK: Creditnote email sent to %s' % creditnote.user.email)
creditnote.sent_to_customer=True
creditnote.save()
else:
self.output('ERROR: Unable to send creditnote email for creditnote %s to %s' % (creditnote.pk, creditnote.user.email))
# pause for a bit # pause for a bit
sleep(60) sleep(60)

View file

@ -25,12 +25,6 @@ class Order(CreatedUpdatedModel):
through='shop.OrderProductRelation' through='shop.OrderProductRelation'
) )
user = models.ForeignKey(
'auth.User',
verbose_name=_('User'),
help_text=_('The user this order belongs to.'),
related_name='orders',
)
paid = models.BooleanField( paid = models.BooleanField(
verbose_name=_('Paid?'), verbose_name=_('Paid?'),
@ -264,17 +258,55 @@ class EpayPayment(CreatedUpdatedModel, UUIDModel):
txnid = models.IntegerField() txnid = models.IntegerField()
class CreditNote(CreatedUpdatedModel):
amount = models.DecimalField()
text = models.TextField()
pdf = models.FileField(
null=True,
blank=True,
upload_to='creditnotes/'
)
user = models.ForeignKey(
'auth.User',
verbose_name=_('User'),
help_text=_('The user this credit note belongs to.'),
related_name='creditnotes',
)
paid = models.BooleanField(
verbose_name=_('Paid?'),
help_text=_('Whether this creditnote has been paid.'),
default=False,
)
sent_to_customer = models.BooleanField(default=False)
def __str__(self):
return 'creditnote#%s - %s DKK (sent to %s: %s)' % (
self.id,
self.amount,
self.user.email,
self.sent_to_customer,
)
@property
def vat(self):
return Decimal(self.total*Decimal(0.2))
@property
def filename(self):
return 'bornhack_creditnote_%s.pdf' % self.pk
class Invoice(CreatedUpdatedModel): class Invoice(CreatedUpdatedModel):
order = models.OneToOneField('shop.Order') order = models.OneToOneField('shop.Order')
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 customer: %s)' % ( return 'invoice#%s - order %s - %s - total %s DKK (sent to %s: %s)' % (
self.id, self.id,
self.order.id, self.order.id,
self.order.created, self.order.created,
self.order.total, self.order.total,
self.order.user.email,
self.sent_to_customer, self.sent_to_customer,
) )

View file

@ -0,0 +1,12 @@
Hello!<br>
<br>
This email contains your creditnote from BornHack.<br>
The creditnote number is <b>{{ creditnote.pk }}</b>.<br>
<br>
The creditnote is attached in PDF format with the filename <b>{{ creditnote.filename }}</b>. The PDF contains the details about what this creditnote covers.<br>
<br>
<br>
Best regards,<br>
<br>
The BornHack Team<br>
<br>

View file

@ -0,0 +1,14 @@
Hello!
This email contains your creditnote from BornHack.
The creditnote number is {{ creditnote.pk }}.
The creditnote is attached in PDF format with
the filename {{ creditnote.filename }}. The PDF
contains the details about what this creditnote
covers.
Best regards,
The BornHack Team

View file

@ -0,0 +1,44 @@
{% 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%;">&nbsp;</td>
<td>
<h3>
{{ creditnote.created|date:"b jS, Y" }}<br>
Creditnote #{{ invoice.pk }}
</h3>
</td>
</tr>
</table>
<h3>Customer: {{ creditnote.order.user.email }}</h3>
<br>
<h2>CREDITNOTE</h2>
<table style="width:90%; margin:1em;">
<tr>
<td>
<b>Text
<td>
<b>Amount
<tr>
<td>
{{ creditnote.text }}
<td>
{{ creditnote.amount|currency }}
<tr>
<td colspan="2">
<td>
<strong>Danish VAT (25%)</strong>
<td>
{{ creditnote.vat|currency }}
<tr>
<td colspan="2">
<td>
<strong>Total</strong>
<td>
{{ creditnote.amount|currency }}
</table>