Add custom filter and remove individual grinds functionality
This commit is contained in:
parent
0f7a36a569
commit
2521beea74
@ -19,7 +19,7 @@ ORDER_REFUND_TEMPLATE = 'storefront/order_refund'
|
||||
def send_order_confirmation_email(order):
|
||||
send_templated_mail(
|
||||
template_name=CONFIRM_ORDER_TEMPLATE,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||||
from_email=settings.ORDER_FROM_EMAIL,
|
||||
recipient_list=[order['email']],
|
||||
context=order
|
||||
)
|
||||
@ -30,7 +30,7 @@ def send_order_confirmation_email(order):
|
||||
def send_order_shipped_email(data):
|
||||
send_templated_mail(
|
||||
template_name=SHIP_ORDER_TEMPLATE,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||||
from_email=settings.ORDER_FROM_EMAIL,
|
||||
recipient_list=[data['email']],
|
||||
context=data
|
||||
)
|
||||
|
||||
@ -32,6 +32,7 @@ ANYMAIL_CONFIG = {
|
||||
SERVER_EMAIL = os.environ.get('SERVER_EMAIL', '')
|
||||
DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL', '')
|
||||
DEFAULT_CONTACT_EMAIL = os.environ.get('DEFAULT_CONTACT_EMAIL', '')
|
||||
ORDER_FROM_EMAIL = os.environ.get('ORDER_FROM_EMAIL', '')
|
||||
STATIC_ROOT_PATH = os.environ.get('STATIC_ROOT_PATH', '/var/www/ptcoffee-dev/static/')
|
||||
|
||||
SECURE_HSTS_SECONDS = os.environ.get('SECURE_HSTS_SECONDS', 3600)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 MiB After Width: | Height: | Size: 2.2 MiB |
@ -218,13 +218,26 @@ input[type=submit]:hover,
|
||||
|
||||
/* Contact form
|
||||
========================================================================== */
|
||||
.contact-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 0 2rem;
|
||||
}
|
||||
|
||||
.contact-form p:nth-child(6) {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.contact-form p:last-child {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.contact-form label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
:is(.contact-form) input, select, textarea {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
|
||||
@ -476,12 +489,15 @@ section:not(:last-child) {
|
||||
background-image: url("/static/images/site_banner.jpg");
|
||||
}
|
||||
.site__banner--fairtrade {
|
||||
padding: 6rem 1rem;
|
||||
background-image: url("/static/images/fairtrade_banner.jpg");
|
||||
}
|
||||
.site__banner--reviews {
|
||||
padding: 6rem 1rem;
|
||||
background-image: url("/static/images/reviews_banner.jpg");
|
||||
}
|
||||
.site__banner--about {
|
||||
padding: 6rem 1rem;
|
||||
background-image: url("/static/images/coffee_banner.jpg");
|
||||
}
|
||||
|
||||
@ -791,6 +807,15 @@ article + article {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.item__form {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.item__form *:not(:last-child) {
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -62,10 +62,12 @@ class Cart:
|
||||
self.session.modified = True
|
||||
logger.info(f'\nCart:\n{self.cart}\n')
|
||||
|
||||
def remove(self, product):
|
||||
def remove(self, product, grind):
|
||||
product_id = str(product.id)
|
||||
if product_id in self.cart:
|
||||
del self.cart[product_id]
|
||||
del self.cart[product_id]['variations'][grind]
|
||||
if not self.cart[product_id]['variations']:
|
||||
del self.cart[product_id]
|
||||
self.save()
|
||||
|
||||
def __iter__(self):
|
||||
|
||||
@ -133,8 +133,7 @@ class ContactForm(forms.Form):
|
||||
(OTHER, 'Other (please describe below)'),
|
||||
]
|
||||
|
||||
first_name = forms.CharField()
|
||||
last_name = forms.CharField()
|
||||
full_name = forms.CharField()
|
||||
email_address = forms.EmailField()
|
||||
referal = forms.ChoiceField(
|
||||
label='How did you find our website?',
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% load grind_filter %}
|
||||
|
||||
{% block head_title %}Cart | {% endblock %}
|
||||
|
||||
@ -15,20 +16,18 @@
|
||||
<img class="item__image" src="{{product.get_first_img.image.url}}" alt="{{product.get_first_img.image}}">
|
||||
</figure>
|
||||
<div class="item__info">
|
||||
<h4>{{product.name}}</h4>
|
||||
<p><strong>Grind</strong>:</p>
|
||||
{% for key, value in item.variations.items %}
|
||||
<p><strong>{{key}}</strong><br>
|
||||
<form class="item__form" action="{% url 'storefront:cart-update' product.pk key %}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ value.update_quantity_form }}
|
||||
<input type="submit" value="Update">
|
||||
</form>
|
||||
</p>
|
||||
{% endfor %}
|
||||
<p>
|
||||
<a href="{% url 'storefront:cart-remove' product.pk %}">Remove from cart</a>
|
||||
<h3>{{product.name}}</h3>
|
||||
<h5>Grind:</h5>
|
||||
{% for key, value in item.variations.items %}
|
||||
<p><strong>{{ key|get_grind_display }}</strong><br>
|
||||
<form class="item__form" action="{% url 'storefront:cart-update' product.pk key %}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ value.update_quantity_form }}
|
||||
<input type="submit" value="Update">
|
||||
<a href="{% url 'storefront:cart-remove' product.pk key %}">Remove item</a>
|
||||
</form>
|
||||
</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="item__price">
|
||||
<p><strong>${{item.price}}</strong></p>
|
||||
|
||||
@ -13,9 +13,9 @@
|
||||
Please contact us, we’re happy to help you over the phone<br>
|
||||
<a href="tel:+13603855856">(360) 385-5856</a> Mon-Fri between 9:00 am and 5:00 pm Pacific Time.
|
||||
</p>
|
||||
<p>Or send us a message using the form below and we'll email you back as soon as we can.</p>
|
||||
</header>
|
||||
<section>
|
||||
<p>Or send us a message using the form below and we'll email you back as soon as we can.</p>
|
||||
<form action="{% url 'storefront:contact' %}" method="post" class="contact-form">
|
||||
{% csrf_token %}
|
||||
{{form.as_p}}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% load grind_filter %}
|
||||
|
||||
{% block head_title %}Checkout | {% endblock %}
|
||||
|
||||
@ -38,7 +39,7 @@
|
||||
<div>
|
||||
<h4>{{product.name}}</h4>
|
||||
{% for key, value in item.variations.items %}
|
||||
<p>Grind: <strong>{{key}}</strong>, Qty: <strong>{{value.quantity}}</strong></p>
|
||||
<p>Grind: <strong>{{ key|get_grind_display }}</strong>, Qty: <strong>{{value.quantity}}</strong></p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="item__price">
|
||||
|
||||
0
src/storefront/templatetags/__init__.py
Normal file
0
src/storefront/templatetags/__init__.py
Normal file
8
src/storefront/templatetags/grind_filter.py
Normal file
8
src/storefront/templatetags/grind_filter.py
Normal file
@ -0,0 +1,8 @@
|
||||
from django import template
|
||||
from core import CoffeeGrind
|
||||
|
||||
def get_grind_display(value):
|
||||
return next((v[1] for i, v in enumerate(CoffeeGrind.GRIND_CHOICES) if v[0] == value), None)
|
||||
|
||||
register = template.Library()
|
||||
register.filter('get_grind_display', get_grind_display)
|
||||
@ -154,7 +154,7 @@ class CartTest(TestCase):
|
||||
update_quantity=False
|
||||
)
|
||||
self.assertEqual(len(cart), 3)
|
||||
cart.remove(self.product)
|
||||
cart.remove(self.product, CoffeeGrind.WHOLE)
|
||||
self.assertEqual(len(cart), 0)
|
||||
|
||||
def test_cart_get_total_weight(self):
|
||||
|
||||
@ -15,7 +15,7 @@ urlpatterns = [
|
||||
path('cart/', views.CartView.as_view(), name='cart-detail'),
|
||||
path('cart/<int:pk>/add/', views.CartAddProductView.as_view(), name='cart-add'),
|
||||
path('cart/<int:pk>/update/<slug:grind>/', views.CartUpdateProductView.as_view(), name='cart-update'),
|
||||
path('cart/<int:pk>/remove/', views.cart_remove_product_view, name='cart-remove'),
|
||||
path('cart/<int:pk>/remove/<slug:grind>/', views.cart_remove_product_view, name='cart-remove'),
|
||||
|
||||
path('coupon/apply/', views.CouponApplyView.as_view(), name='coupon-apply'),
|
||||
|
||||
|
||||
@ -104,10 +104,10 @@ class CartUpdateProductView(SingleObjectMixin, FormView):
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
def cart_remove_product_view(request, pk):
|
||||
def cart_remove_product_view(request, pk, grind):
|
||||
cart = Cart(request)
|
||||
product = get_object_or_404(Product, id=pk)
|
||||
cart.remove(product)
|
||||
cart.remove(product, grind)
|
||||
return redirect('storefront:cart-detail')
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
{% block plain %}
|
||||
Referred from: {{referal}}
|
||||
|
||||
From: {{first_name}} {{last_name}} {{email_address}}
|
||||
From: {{full_name}} {{email_address}}
|
||||
|
||||
Message: {{message}}
|
||||
{% endblock %}
|
||||
@ -10,7 +10,7 @@
|
||||
{% block html %}
|
||||
<p><strong>Referred from</strong>:<br>{{referal}}</p>
|
||||
|
||||
<p><strong>From</strong>:<br>{{first_name}} {{last_name}} {{email_address|urlize}}</p>
|
||||
<p><strong>From</strong>:<br>{{full_name}} {{email_address|urlize}}</p>
|
||||
|
||||
<p><strong>Message</strong>:<br>{{message|linebreaks}}</p>
|
||||
{% endblock %}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
Hi {{full_name}}, we're getting your order ready to be shipped. We will notify you when it has been sent.
|
||||
|
||||
If you have any questions, reply to this email or contact us at support@ptcoffee.com
|
||||
If you have any questions, send us an email at support@ptcoffee.com.
|
||||
|
||||
Thanks,
|
||||
Port Townsend Roasting Co.
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
<p>Hi {{full_name}}, we're getting your order ready to be shipped. We will notify you when it has been sent.</p>
|
||||
|
||||
<p>If you have any questions, reply to this email or contact us at <a href="mailto:support@ptcoffee.com">support@ptcoffee.com</a></p>
|
||||
<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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user