from __future__ import absolute_import, unicode_literals
from decimal import Decimal
from django.utils.text import capfirst
from django.utils.translation import activate, ugettext as _
try:
from django.urls import get_callable
except ImportError:
from django.core.urlresolvers import get_callable
import plata
from pdfdocument.document import cm, mm
from pdfdocument.elements import create_stationery_fn
class OrderReport(object):
def __init__(self, pdf, order):
self.pdf = pdf
self.order = order
if order.language_code:
activate(order.language_code)
def init_letter(self):
self.pdf.init_letter(
page_fn=create_stationery_fn(
get_callable(plata.settings.PLATA_REPORTING_STATIONERY)()
)
)
def address(self, address_key):
"""
``address_key`` must be one of ``shipping`` and ``billing``.
"""
if plata.settings.PLATA_REPORTING_ADDRESSLINE:
self.pdf.address_head(plata.settings.PLATA_REPORTING_ADDRESSLINE)
self.pdf.address(self.order.addresses()[address_key])
self.pdf.next_frame()
def title(self, title=None):
self.pdf.p(
"%s: %s"
% (
capfirst(_("order date")),
self.order.confirmed.strftime("%d.%m.%Y")
if self.order.confirmed
else _("Not confirmed yet"),
)
)
self.pdf.spacer(3 * mm)
if not title:
title = _("Order")
self.pdf.h1("%s %s" % (title, self.order.order_id))
self.pdf.hr()
def items_without_prices(self):
self.pdf.table(
[(_("SKU"), capfirst(_("product")), capfirst(_("quantity")))]
+ [(item.sku, item.name, item.quantity) for item in self.order.items.all()],
(2 * cm, 13.4 * cm, 1 * cm),
self.pdf.style.tableHead + (("ALIGN", (1, 0), (1, -1), "LEFT"),),
)
def items_with_prices(self):
self.pdf.table(
[
(
_("SKU"),
capfirst(_("product")),
capfirst(_("quantity")),
capfirst(_("unit price")),
capfirst(_("line item price")),
)
]
+ [
(
item.sku,
item.name,
item.quantity,
"%.2f" % item.unit_price,
"%.2f" % item.discounted_subtotal,
)
for item in self.order.items.all()
],
(2 * cm, 6 * cm, 1 * cm, 3 * cm, 4.4 * cm),
self.pdf.style.tableHead + (("ALIGN", (1, 0), (1, -1), "LEFT"),),
)
def summary(self):
summary_table = [
("", ""),
(capfirst(_("subtotal")), "%.2f" % self.order.subtotal),
]
if self.order.discount:
summary_table.append(
(capfirst(_("discount")), "%.2f" % self.order.discount)
)
if self.order.shipping:
summary_table.append(
(capfirst(_("shipping")), "%.2f" % self.order.shipping)
)
self.pdf.table(summary_table, (12 * cm, 4.4 * cm), self.pdf.style.table)
self.pdf.spacer(1 * mm)
total_title = "%s %s" % (capfirst(_("total")), self.order.currency)
if self.order.tax:
if "tax_details" in self.order.data:
zero = Decimal("0.00")
self.pdf.table(
[
(
"",
"%s %s" % (_("Incl. tax"), "%.1f%%" % row["tax_rate"]),
row["total"].quantize(zero),
row["tax_amount"].quantize(zero),
"",
)
for rate, row in self.order.data["tax_details"]
if row["tax_amount"]
],
(2 * cm, 4 * cm, 3 * cm, 3 * cm, 4.4 * cm),
self.pdf.style.table,
)
self.pdf.table(
[(total_title, "%.2f" % self.order.total)],
(12 * cm, 4.4 * cm),
self.pdf.style.tableHead,
)
self.pdf.spacer()
def payment(self):
if not self.order.balance_remaining:
try:
payment = self.order.payments.authorized()[0]
except IndexError:
payment = None
if payment and payment.payment_method:
self.pdf.p(
_("Already paid for with: %(payment_method)s.")
% {
"payment_method": payment.payment_method
+ (
(
" (Transaction %(transaction)s)"
% {"transaction": payment.transaction_id}
)
if payment.transaction_id
else ""
)
}
)
else:
self.pdf.p(_("Already paid for."))
else:
self.pdf.p(_("Not paid yet."))
def notes(self):
if self.order.notes:
self.pdf.spacer(10 * mm)
self.pdf.p(capfirst(_("notes")), style=self.pdf.style.bold)
self.pdf.spacer(1 * mm)
self.pdf.p(self.order.notes)
def address_table(self):
self.pdf.table(
[
(_("Seller"), _("Customer")),
(plata.settings.PLATA_REPORTING_ADDRESSLINE, self.get_address_data()),
],
(8.2 * cm, 8.2 * cm),
self.pdf.style.tableBase
+ (
(
"FONT",
(0, 0),
(-1, 0),
"%s-Bold" % self.pdf.style.fontName,
self.pdf.style.fontSize,
),
("TOPPADDING", (0, 0), (-1, -1), 1),
("BOTTOMPADDING", (0, 0), (-1, -1), 2),
("ALIGN", (1, 0), (1, -1), "LEFT"),
),
)
self.pdf.spacer(10 * mm)
self.pdf.next_frame()
def get_address_data(self, prefix=""):
# overrided so we can just return address as text
obj = self.order.addresses()["billing"]
if type(obj) == dict:
data = obj
else:
data = {}
for field in (
"company",
"manner_of_address",
"first_name",
"last_name",
"address",
"zip_code",
"city",
"full_override",
):
attribute = "%s%s" % (prefix, field)
data[field] = getattr(obj, attribute, "").strip()
address = []
if data.get("company", False):
address.append(data["company"])
title = data.get("manner_of_address", "")
if title:
title += " "
if data.get("first_name", False):
address.append(
"%s%s %s"
% (title, data.get("first_name", ""), data.get("last_name", ""))
)
else:
address.append("%s%s" % (title, data.get("last_name", "")))
address.append(data.get("address"))
address.append("%s %s" % (data.get("zip_code", ""), data.get("city", "")))
if data.get("full_override"):
address = [
l.strip()
for l in data.get("full_override").replace("\r", "").splitlines()
]
return "\n".join(address)
[docs]def invoice_pdf(pdf, order):
"""PDF suitable for use as invoice"""
report = OrderReport(pdf, order)
report.init_letter()
report.address_table()
report.title()
report.items_with_prices()
report.summary()
report.payment()
pdf.generate()
[docs]def packing_slip_pdf(pdf, order):
"""PDF suitable for use as packing slip"""
report = OrderReport(pdf, order)
report.init_letter()
report.address("shipping")
report.title()
report.items_without_prices()
report.notes()
pdf.generate()