Finalize wholesale orders

This commit is contained in:
Nathan Chapman 2023-08-22 21:57:28 -06:00
parent 10cd9cf0c5
commit b61114babb
21 changed files with 536 additions and 27 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.6 on 2023-08-06 18:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0009_wholesaleorder'),
]
operations = [
migrations.AddField(
model_name='wholesaleorder',
name='is_cancelled',
field=models.BooleanField(default=False),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.6 on 2023-08-06 18:53
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0010_wholesaleorder_is_cancelled'),
]
operations = [
migrations.AlterModelOptions(
name='wholesaleorder',
options={'ordering': ['-created_at'], 'verbose_name': 'wholesale order', 'verbose_name_plural': 'wholesale orders'},
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.6 on 2023-08-23 01:28
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0011_alter_wholesaleorder_options'),
]
operations = [
migrations.RenameField(
model_name='wholesaleorder',
old_name='fulfilled',
new_name='is_fulfilled',
),
]

View File

@ -754,7 +754,8 @@ class WholesaleOrder(models.Model):
size=2, size=2,
) )
fulfilled = models.BooleanField(default=False) is_fulfilled = models.BooleanField(default=False)
is_cancelled = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
@ -762,4 +763,5 @@ class WholesaleOrder(models.Model):
class Meta: class Meta:
verbose_name = "wholesale order" verbose_name = "wholesale order"
verbose_name_plural = "wholesale orders" verbose_name_plural = "wholesale orders"
ordering = ['-created_at']

View File

@ -11,8 +11,9 @@ logger = get_task_logger(__name__)
CONFIRM_ORDER_TEMPLATE = 'storefront/order_confirmation' CONFIRM_ORDER_TEMPLATE = 'storefront/order_confirmation'
SHIP_ORDER_TEMPLATE = 'storefront/order_shipped' SHIP_ORDER_TEMPLATE = 'storefront/order_shipped'
ORDER_CANCEl_TEMPLATE = 'storefront/order_cancel' ORDER_CANCEL_TEMPLATE = 'storefront/order_cancel'
ORDER_REFUND_TEMPLATE = 'storefront/order_refund' ORDER_REFUND_TEMPLATE = 'storefront/order_refund'
CONFIRM_WHOLESALE_ORDER_TEMPLATE = 'storefront/wholesale_order_confirmation'
@shared_task(name='send_order_confirmation_email') @shared_task(name='send_order_confirmation_email')
@ -27,6 +28,18 @@ def send_order_confirmation_email(order):
logger.info(f"Order confirmation email sent to {order['email']}") logger.info(f"Order confirmation email sent to {order['email']}")
@shared_task(name='send_wholesale_order_confirmation_email')
def send_wholesale_order_confirmation_email(order):
send_templated_mail(
template_name=CONFIRM_WHOLESALE_ORDER_TEMPLATE,
from_email=SiteSettings.load().order_from_email,
recipient_list=[order['email']],
context=order
)
logger.info(f"WholesaleOrder confirmation email sent to {order['email']}")
@shared_task(name='send_order_shipped_email') @shared_task(name='send_order_shipped_email')
def send_order_shipped_email(data): def send_order_shipped_email(data):
send_templated_mail( send_templated_mail(

View File

@ -4,6 +4,7 @@ from django import forms
from core import OrderStatus from core import OrderStatus
from core.models import ( from core.models import (
ProductVariant, ProductVariant,
WholesaleOrder,
Order, Order,
OrderLine, OrderLine,
ShippingRate, ShippingRate,
@ -118,6 +119,24 @@ OrderTrackingFormset = forms.inlineformset_factory(
) )
class WholesaleOrderCancelForm(forms.ModelForm):
class Meta:
model = WholesaleOrder
fields = ['is_cancelled']
widgets = {
'is_cancelled': forms.HiddenInput()
}
class WholesaleOrderFulfillForm(forms.ModelForm):
class Meta:
model = WholesaleOrder
fields = ['is_fulfilled']
widgets = {
'is_fulfilled': forms.HiddenInput()
}
class ProductPhotoForm(forms.ModelForm): class ProductPhotoForm(forms.ModelForm):
class Meta: class Meta:
model = ProductPhoto model = ProductPhoto

View File

@ -0,0 +1,28 @@
<thead>
<tr>
<th>Order No.</th>
<th>Date</th>
<th>Customer</th>
<th>Fulfillment</th>
</tr>
</thead>
<tbody>
{% for order in order_list %}
<tr class="is-link" onclick="window.location='{% url 'dashboard:wholesale-order-detail' order.pk %}'">
<td>No. {{ order.pk }}</td>
<td>{{ order.created_at|date:"D, M j Y" }}</td>
<td>{{ order.customer.get_full_name }}</td>
<td>
<div class="status-display">
{% if order.is_fulfilled %}
<span class="status-dot {% if order.is_fulfilled %} status-success {% else %} status-info {% endif %}"></span> Fulfilled
{% elif order.is_cancelled %}
Cancelled
{% else %}
<span class="status-dot status-error"></span> Unfulfilled
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -0,0 +1,26 @@
{% extends 'dashboard.html' %}
{% block head_title %}Cancel Wholesale Order No. {{ order.pk }} | {% endblock %}
{% block content %}
<article>
<p>
<a href="{% url 'dashboard:wholesale-order-detail' order.pk %}">&larr; Back</a>
</p>
<header>
<h1>Cancel Wholesale Order No. {{order.pk}}</h1>
</header>
<section class="panel">
<header class="panel-header">
<h4>Are you sure you want to cancel Wholesale Order No. {{ order.pk }}?</h4>
</header>
<form method="POST" class="panel-form">
{% csrf_token %}
{{ form.as_p }}
<p>
<input class="btn btn-warning" type="submit" value="Cancel order">
</p>
</form>
</section>
</article>
{% endblock content %}

View File

@ -0,0 +1,108 @@
{% extends 'dashboard.html' %}
{% load static %}
{% block head_title %}Order No. {{ order.pk }} | {% endblock %}
{% block content %}
<article>
<p>
<a href="{% url 'dashboard:wholesale-order-list' %}">&larr; Back to wholesale</a>
</p>
<header class="object-header">
<h1><img src="{% static 'images/pallet.png' %}"> Wholesale Order No. {{order.pk}}</h1>
{% if perms.core.cancel_order and not order.is_cancelled %}
<a class="btn btn-warning" href="{% url 'dashboard:wholesale-order-cancel' order.pk %}">Cancel order</a>
{% endif %}
</header>
<section class="panel">
<header class="panel-header">
<h4>Details</h4>
</header>
<dl class="panel-datalist">
<dt>Date</dt>
<dd>{{ order.created_at }}</dd>
<dt>Customer</dt>
<dd>
<a href="{% url 'dashboard:customer-detail' order.customer.pk %}">{{order.customer.get_full_name}}</a>&emsp;
<a href="mailto:{{order.customer.email}}">{{order.customer.email}} &nearr;</a>
</dd>
<dt>Status</dt>
<dd>
{% if order.is_fulfilled %}
<span class="status status-success">Fulfilled</span>
{% elif order.is_cancelled %}
Cancelled
{% else %}
<span class="status status-error">Unfulfilled</span>
{% endif %}
</dd>
</dl>
</section>
<section class="panel">
<header class="panel-header">
<h4>Items</h4>
<a href="{% url 'dashboard:wholesale-order-fulfill' order.pk %}" class="btn">Fulfill order &rarr;</a>
</header>
<table>
<tdead>
<tr>
<th>Product</th>
<th>16 oz.</th>
<th>5 lb.</th>
</tr>
</tdead>
<tbody>
<tr>
<td>Brazil</td>
{% for qty in order.brazil %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr>
<tr>
<td>Dante's Tornado</td>
{% for qty in order.dantes_tornado %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Decaf</td>
{% for qty in order.decaf %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Ethiopia</td>
{% for qty in order.ethiopia %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Loop d' Loop</td>
{% for qty in order.loop_d_loop %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Moka Java</td>
{% for qty in order.moka_java %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Nicaragua</td>
{% for qty in order.nicaragua %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Pantomime</td>
{% for qty in order.pantomime %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Sumatra</td>
{% for qty in order.sumatra %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr>
</tbody>
</table>
</section>
</article>
{% endblock content %}

View File

@ -0,0 +1,26 @@
{% extends 'dashboard.html' %}
{% block head_title %}Fulfill Wholesale Order No. {{ order.pk }} | {% endblock %}
{% block content %}
<article>
<p>
<a href="{% url 'dashboard:wholesale-order-detail' order.pk %}">&larr; Back</a>
</p>
<header>
<h1>Fulfill Wholesale Order No. {{order.pk}}</h1>
</header>
<section class="panel">
<header class="panel-header">
<h4>Are you sure you want to fulfill Wholesale Order No. {{ order.pk }}?</h4>
</header>
<form method="POST" class="panel-form">
{% csrf_token %}
{{ form.as_p }}
<p>
<input class="btn" type="submit" value="Fulfill order">
</p>
</form>
</section>
</article>
{% endblock content %}

View File

@ -0,0 +1,40 @@
{% extends 'dashboard.html' %}
{% load static %}
{% block head_title %}Wholesale Orders | {% endblock %}
{% block content %}
<article>
<header>
<h1><img src="{% static "images/pallet.png" %}"> Wholesale Orders</h1>
</header>
<section class="panel">
<header class="panel-header">
</header>
<table>
{% include 'dashboard/wholesale_order/_table.html' with order_list=order_list %}
<tfoot>
<tr>
<td colspan="6">
<div class="pagination">
{% if page_obj.has_previous %}
<a href="?page=1">&laquo; first</a>
<a href="?page={{ page_obj.previous_page_number }}"> previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next </a>
<a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
{% endif %}
</div>
</td>
</tr>
</tfoot>
</table>
</section>
</article>
{% endblock content %}

View File

@ -254,4 +254,28 @@ urlpatterns = [
name='customer-update' name='customer-update'
), ),
])), ])),
# Wholesale Orders
path(
'wholesale-orders/',
views.WholesaleOrderListView.as_view(),
name='wholesale-order-list'
),
path('wholesale-orders/<int:pk>/', include([
path(
'',
views.WholesaleOrderDetailView.as_view(),
name='wholesale-order-detail'
),
path(
'fulfill/',
views.WholesaleOrderFulfillView.as_view(),
name='wholesale-order-fulfill'
),
path(
'cancel/',
views.WholesaleOrderCancelView.as_view(),
name='wholesale-order-cancel'
),
])),
] ]

View File

@ -43,6 +43,7 @@ from core.models import (
Transaction, Transaction,
TrackingNumber, TrackingNumber,
Coupon, Coupon,
WholesaleOrder,
SiteSettings SiteSettings
) )
@ -57,6 +58,8 @@ from .forms import (
OrderLineFormset, OrderLineFormset,
OrderCancelForm, OrderCancelForm,
OrderTrackingFormset, OrderTrackingFormset,
WholesaleOrderFulfillForm,
WholesaleOrderCancelForm,
CouponForm, CouponForm,
ProductPhotoForm ProductPhotoForm
) )
@ -723,3 +726,53 @@ class CustomerUpdateView(
def get_success_url(self): def get_success_url(self):
return reverse('dashboard:customer-detail', kwargs={'pk': self.object.pk}) return reverse('dashboard:customer-detail', kwargs={'pk': self.object.pk})
class WholesaleOrderListView(LoginRequiredMixin, ListView):
model = WholesaleOrder
template_name = 'dashboard/wholesale_order/list.html'
context_object_name = 'order_list'
paginate_by = 50
class WholesaleOrderDetailView(
LoginRequiredMixin, DetailView
):
model = WholesaleOrder
context_object_name = 'order'
template_name = 'dashboard/wholesale_order/detail.html'
class WholesaleOrderCancelView(
LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UpdateView
):
permission_required = 'core.cancel_order'
model = WholesaleOrder
context_object_name = 'order'
template_name = 'dashboard/wholesale_order/cancel_form.html'
form_class = WholesaleOrderCancelForm
success_message = 'Wholesale Order canceled.'
initial = {
'is_cancelled': True
}
def get_success_url(self):
return reverse('dashboard:wholesale-order-detail', kwargs={'pk': self.object.pk})
class WholesaleOrderFulfillView(
LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UpdateView
):
permission_required = 'core.change_wholesaleorder'
model = WholesaleOrder
context_object_name = 'order'
template_name = 'dashboard/wholesale_order/fulfill_form.html'
form_class = WholesaleOrderFulfillForm
success_message = 'Wholesale Order fulfilled.'
initial = {
'is_fulfilled': True
}
def get_success_url(self):
return reverse('dashboard:wholesale-order-detail', kwargs={'pk': self.object.pk})

BIN
static/images/pallet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -1141,8 +1141,15 @@ footer > section {
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 3rem; gap: 3rem;
} }
.wholesale-detail,
.wholesale-fields {
width: fit-content;
}
.wholesale-field { .wholesale-field {
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
gap: 0.5rem; gap: 0.5rem;
margin-bottom: 1rem;
} }

View File

@ -6,17 +6,23 @@
<h1>Wholesale</h1> <h1>Wholesale</h1>
</header> </header>
{% if user.is_authenticated %} {% if user.is_authenticated and perms.core.add_wholesaleorder %}
<section> <section>
<p><a href="{% url 'storefront:wholesale-order-create' %}" class="btn">New wholesale order</a></p> <p><a href="{% url 'storefront:wholesale-order-create' %}" class="btn">New wholesale order</a></p>
<h3>Orders</h3>
<table> <table>
{% for order in user.wholesale_orders.all %} {% for order in user.wholesale_orders.all %}
<tr> <tr>
<td>{{ order.created_at }}</td>
<td> <td>
<a href="{% url 'storefront:wholesale-order-detail' user.pk order.pk %}"No. {{ order.pk }}</a> <a href="{% url 'storefront:wholesale-order-detail' user.pk order.pk %}">
No. {{ order.pk }} | {{ order.created_at }}
</a>
</td> </td>
</tr> </tr>
{% empty %}
<tr>
<td>No wholesale order placed yet.</td>
</tr>
{% endfor %} {% endfor %}
</table> </table>
{% else %} {% else %}

View File

@ -3,65 +3,64 @@
{% block content %} {% block content %}
<article> <article>
<p><a href="{% url 'storefront:customer-detail' customer.pk %}">&larr; Back</a></p> <p><a href="{% url 'storefront:wholesale-order' %}">&larr; Back</a></p>
<header> <header>
<h1>Wholesale Order No. {{order.pk}}</h1> <h1>Wholesale Order No. {{order.pk}}</h1>
<h3>Placed on {{order.created_at|date:"M j, Y"}}</h3> <h3>Placed on {{order.created_at|date:"M j, Y"}}</h3>
</header> </header>
<section> <section>
<table> <table class="wholesale-detail">
<thead> <thead>
<tr> <tr>
<th>Product</th> <th>Product</th>
<th>16 oz</th> <th>16 oz.</th>
<th>5 lb</th> <th>5 lb.</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th>Brazil</th> <td>Brazil</td>
{% for qty in order.brazil %} {% for qty in order.brazil %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr> </tr><tr>
<tr> <td>Dante's Tornado</td>
<th>Dante's Tornado</th>
{% for qty in order.dantes_tornado %} {% for qty in order.dantes_tornado %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr><tr> </tr><tr>
<th>Decaf</th> <td>Decaf</td>
{% for qty in order.decaf %} {% for qty in order.decaf %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr><tr> </tr><tr>
<th>Ethiopia</th> <td>Ethiopia</td>
{% for qty in order.ethiopia %} {% for qty in order.ethiopia %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr><tr> </tr><tr>
<th>Loop d' Loop</th> <td>Loop d' Loop</td>
{% for qty in order.loop_d_loop %} {% for qty in order.loop_d_loop %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr><tr> </tr><tr>
<th>Moka Java</th> <td>Moka Java</td>
{% for qty in order.moka_java %} {% for qty in order.moka_java %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr><tr> </tr><tr>
<th>Nicaragua</th> <td>Nicaragua</td>
{% for qty in order.nicaragua %} {% for qty in order.nicaragua %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr><tr> </tr><tr>
<th>Pantomime</th> <td>Pantomime</td>
{% for qty in order.pantomime %} {% for qty in order.pantomime %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}
</tr><tr> </tr><tr>
<th>Sumatra</th> <td>Sumatra</td>
{% for qty in order.sumatra %} {% for qty in order.sumatra %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td> <td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %} {% endfor %}

View File

@ -39,6 +39,7 @@ from moneyed import Money, USD
from accounts.models import User from accounts.models import User
from accounts.utils import get_or_create_customer from accounts.utils import get_or_create_customer
from accounts.forms import CustomerUpdateForm, CustomerShippingAddressUpdateForm from accounts.forms import CustomerUpdateForm, CustomerShippingAddressUpdateForm
from core.tasks import send_wholesale_order_confirmation_email
from core.models import ( from core.models import (
ProductCategory, Product, ProductVariant, ProductOption, ProductCategory, Product, ProductVariant, ProductOption,
Order, Transaction, OrderLine, Coupon, ShippingRate, Order, Transaction, OrderLine, Coupon, ShippingRate,
@ -850,9 +851,9 @@ class WholesaleOrderView(TemplateView):
class WholesaleOrderCreateView( class WholesaleOrderCreateView(
PermissionRequiredMixin, LoginRequiredMixin, CreateView, SuccessMessageMixin PermissionRequiredMixin, LoginRequiredMixin, SuccessMessageMixin, CreateView
): ):
permission_required = "core.create_wholesaleorder" permission_required = "core.add_wholesaleorder"
model = WholesaleOrder model = WholesaleOrder
template_name = 'storefront/wholesale_order_create_form.html' template_name = 'storefront/wholesale_order_create_form.html'
form_class = WholesaleOrderCreateForm form_class = WholesaleOrderCreateForm
@ -867,6 +868,22 @@ class WholesaleOrderCreateView(
def form_valid(self, form): def form_valid(self, form):
form.instance.customer = self.request.user form.instance.customer = self.request.user
self.object = form.save()
order = {
'order_id': self.object.pk,
'full_name': self.object.customer.get_full_name(),
'email': self.object.customer.email,
'brazil': self.object.brazil,
'dantes_tornado': self.object.dantes_tornado,
'decaf': self.object.decaf,
'ethiopia': self.object.ethiopia,
'loop_d_loop': self.object.loop_d_loop,
'moka_java': self.object.moka_java,
'nicaragua': self.object.nicaragua,
'pantomime': self.object.pantomime,
'sumatra': self.object.sumatra
}
send_wholesale_order_confirmation_email.delay(order)
return super().form_valid(form) return super().form_valid(form)

View File

@ -87,11 +87,11 @@
</header> </header>
<main> <main>
{% if messages %} {% if messages %}
<section class="messages"> <section class="messages">
{% for message in messages %} {% for message in messages %}
<p {% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</p> <p {% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</p>
{% endfor %} {% endfor %}
</section> </section>
{% endif %} {% endif %}
{% block content %} {% block content %}
{% endblock content %} {% endblock content %}

View File

@ -48,6 +48,10 @@
<img src="{% static 'images/box.png' %}"> <img src="{% static 'images/box.png' %}">
Orders Orders
</a> </a>
<a href="{% url 'dashboard:wholesale-order-list' %}">
<img src="{% static 'images/pallet.png' %}">
Wholesale
</a>
<a href="{% url 'dashboard:customer-list' %}"> <a href="{% url 'dashboard:customer-list' %}">
<img src="{% static 'images/customer.png' %}"> <img src="{% static 'images/customer.png' %}">
Customers Customers

View File

@ -0,0 +1,84 @@
{% block subject %}PT Coffee: Confirmation for Wholesale Order No. {{ order_id }}{% endblock %}
{% block html %}
<head>
<style>
table {
border-collapse: collapse;
text-align: left;
}
th, td, tr {
border: 1px solid black;
}
th, td {
padding: 8px;
}
</style>
</head>
<h3>Thank you for your order!</h3>
<p>Hi {{ full_name }}, your order details are below.</p>
<h4>Order Summary</h4>
<table>
<thead>
<tr>
<th>Product</th>
<th>16 oz.</th>
<th>5 lb.</th>
</tr>
</thead>
<tbody>
<tr>
<td>Brazil</td>
{% for qty in brazil %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Dante's Tornado</td>
{% for qty in dantes_tornado %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Decaf</td>
{% for qty in decaf %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Ethiopia</td>
{% for qty in ethiopia %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Loop d' Loop</td>
{% for qty in loop_d_loop %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Moka Java</td>
{% for qty in moka_java %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Nicaragua</td>
{% for qty in nicaragua %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Pantomime</td>
{% for qty in pantomime %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr><tr>
<td>Sumatra</td>
{% for qty in sumatra %}
<td>{% if qty %}Qty: {{ qty }}{% endif %}</td>
{% endfor %}
</tr>
</tbody>
</table>
<p>If you have any questions, send us an email at <a href="mailto:support@ptcoffee.com">support@ptcoffee.com</a>.</p>
<p>Thanks,<br>
Port Townsend Roasting Co.</p>
{% endblock %}