Add specific shipping choice when 6 bags are in the cart
This commit is contained in:
parent
b9b5eb5254
commit
44e73ca790
@ -2,103 +2,105 @@ from django.conf import settings
|
|||||||
|
|
||||||
|
|
||||||
class DiscountValueType:
|
class DiscountValueType:
|
||||||
FIXED = "fixed"
|
FIXED = 'fixed'
|
||||||
PERCENTAGE = "percentage"
|
PERCENTAGE = 'percentage'
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(FIXED, settings.DEFAULT_CURRENCY),
|
(FIXED, settings.DEFAULT_CURRENCY),
|
||||||
(PERCENTAGE, "%"),
|
(PERCENTAGE, '%'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class VoucherType:
|
class VoucherType:
|
||||||
SHIPPING = "shipping"
|
SHIPPING = 'shipping'
|
||||||
ENTIRE_ORDER = "entire_order"
|
ENTIRE_ORDER = 'entire_order'
|
||||||
SPECIFIC_PRODUCT = "specific_product"
|
SPECIFIC_PRODUCT = 'specific_product'
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(ENTIRE_ORDER, "Entire order"),
|
(ENTIRE_ORDER, 'Entire order'),
|
||||||
(SHIPPING, "Shipping"),
|
(SHIPPING, 'Shipping'),
|
||||||
(SPECIFIC_PRODUCT, "Specific products, collections and categories"),
|
(SPECIFIC_PRODUCT, 'Specific products, collections and categories'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class OrderStatus:
|
class OrderStatus:
|
||||||
DRAFT = "draft" # fully editable, not finalized order created by staff users
|
DRAFT = 'draft' # fully editable, not finalized order created by staff users
|
||||||
UNFULFILLED = "unfulfilled" # order with no items marked as fulfilled
|
UNFULFILLED = 'unfulfilled' # order with no items marked as fulfilled
|
||||||
PARTIALLY_FULFILLED = (
|
PARTIALLY_FULFILLED = (
|
||||||
"partially_fulfilled" # order with some items marked as fulfilled
|
'partially_fulfilled' # order with some items marked as fulfilled
|
||||||
)
|
)
|
||||||
FULFILLED = "fulfilled" # order with all items marked as fulfilled
|
FULFILLED = 'fulfilled' # order with all items marked as fulfilled
|
||||||
|
|
||||||
PARTIALLY_RETURNED = (
|
PARTIALLY_RETURNED = (
|
||||||
"partially_returned" # order with some items marked as returned
|
'partially_returned' # order with some items marked as returned
|
||||||
)
|
)
|
||||||
RETURNED = "returned" # order with all items marked as returned
|
RETURNED = 'returned' # order with all items marked as returned
|
||||||
CANCELED = "canceled" # permanently canceled order
|
CANCELED = 'canceled' # permanently canceled order
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(DRAFT, "Draft"),
|
(DRAFT, 'Draft'),
|
||||||
(UNFULFILLED, "Unfulfilled"),
|
(UNFULFILLED, 'Unfulfilled'),
|
||||||
(PARTIALLY_FULFILLED, "Partially fulfilled"),
|
(PARTIALLY_FULFILLED, 'Partially fulfilled'),
|
||||||
(PARTIALLY_RETURNED, "Partially returned"),
|
(PARTIALLY_RETURNED, 'Partially returned'),
|
||||||
(RETURNED, "Returned"),
|
(RETURNED, 'Returned'),
|
||||||
(FULFILLED, "Fulfilled"),
|
(FULFILLED, 'Fulfilled'),
|
||||||
(CANCELED, "Canceled"),
|
(CANCELED, 'Canceled'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TransactionStatus:
|
class TransactionStatus:
|
||||||
CREATED = "CREATED" # The order was created with the specified context.
|
CREATED = 'CREATED' # The order was created with the specified context.
|
||||||
SAVED = "SAVED" # The order was saved and persisted. The order status continues to be in progress until a capture is made with final_capture = true for all purchase units within the order.
|
SAVED = 'SAVED' # The order was saved and persisted. The order status continues to be in progress until a capture is made with final_capture = true for all purchase units within the order.
|
||||||
APPROVED = "APPROVED" # The customer approved the payment through the PayPal wallet or another form of guest or unbranded payment. For example, a card, bank account, or so on.
|
APPROVED = 'APPROVED' # The customer approved the payment through the PayPal wallet or another form of guest or unbranded payment. For example, a card, bank account, or so on.
|
||||||
VOIDED = "VOIDED" # All purchase units in the order are voided.
|
VOIDED = 'VOIDED' # All purchase units in the order are voided.
|
||||||
COMPLETED = "COMPLETED" # The payment was authorized or the authorized payment was captured for the order.
|
COMPLETED = 'COMPLETED' # The payment was authorized or the authorized payment was captured for the order.
|
||||||
PAYER_ACTION_REQUIRED = "PAYER_ACTION_REQUIRED" # The order requires an action from the payer (e.g. 3DS authentication). Redirect the payer to the "rel":"payer-action" HATEOAS link returned as part of the response prior to authorizing or capturing the order.
|
PAYER_ACTION_REQUIRED = 'PAYER_ACTION_REQUIRED' # The order requires an action from the payer (e.g. 3DS authentication). Redirect the payer to the 'rel':'payer-action' HATEOAS link returned as part of the response prior to authorizing or capturing the order.
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(CREATED, "Created"),
|
(CREATED, 'Created'),
|
||||||
(SAVED, "Saved"),
|
(SAVED, 'Saved'),
|
||||||
(APPROVED, "Approved"),
|
(APPROVED, 'Approved'),
|
||||||
(VOIDED, "Voided"),
|
(VOIDED, 'Voided'),
|
||||||
(COMPLETED, "Completed"),
|
(COMPLETED, 'Completed'),
|
||||||
(PAYER_ACTION_REQUIRED, "Payer action required")
|
(PAYER_ACTION_REQUIRED, 'Payer action required')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ShippingMethodType:
|
class ShippingMethodType:
|
||||||
PRICE_BASED = "price"
|
PRICE_BASED = 'price'
|
||||||
WEIGHT_BASED = "weight"
|
WEIGHT_BASED = 'weight'
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(PRICE_BASED, "Price based shipping"),
|
(PRICE_BASED, 'Price based shipping'),
|
||||||
(WEIGHT_BASED, "Weight based shipping"),
|
(WEIGHT_BASED, 'Weight based shipping'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ShippingService:
|
class ShippingService:
|
||||||
FIRST_CLASS = "FIRST CLASS"
|
FIRST_CLASS = 'FIRST CLASS'
|
||||||
PRIORITY = "PRIORITY"
|
PRIORITY = 'PRIORITY'
|
||||||
PRIORITY_COMMERCIAL = "PRIORITY COMMERCIAL"
|
PRIORITY_COMMERCIAL = 'PRIORITY COMMERCIAL'
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(FIRST_CLASS, "First Class"),
|
(FIRST_CLASS, 'First Class'),
|
||||||
(PRIORITY, "Priority"),
|
(PRIORITY, 'Priority'),
|
||||||
(PRIORITY_COMMERCIAL, "Priority Commercial")
|
(PRIORITY_COMMERCIAL, 'Priority Commercial')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ShippingContainer:
|
class ShippingContainer:
|
||||||
LG_FLAT_RATE_BOX = "LG FLAT RATE BOX"
|
LG_FLAT_RATE_BOX = 'LG FLAT RATE BOX'
|
||||||
REGIONAL_RATE_BOX_A = "REGIONALRATEBOXA"
|
MD_FLAT_RATE_BOX = 'MD FLAT RATE BOX'
|
||||||
REGIONAL_RATE_BOX_B = "REGIONALRATEBOXB"
|
REGIONAL_RATE_BOX_A = 'REGIONALRATEBOXA'
|
||||||
VARIABLE = "VARIABLE"
|
REGIONAL_RATE_BOX_B = 'REGIONALRATEBOXB'
|
||||||
|
VARIABLE = 'VARIABLE'
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(LG_FLAT_RATE_BOX, "Flate Rate Box - Large"),
|
(LG_FLAT_RATE_BOX, 'Flate Rate Box - Large'),
|
||||||
(REGIONAL_RATE_BOX_A, "Regional Rate Box A"),
|
(MD_FLAT_RATE_BOX, 'Flate Rate Box - Medium'),
|
||||||
(REGIONAL_RATE_BOX_B, "Regional Rate Box B"),
|
(REGIONAL_RATE_BOX_A, 'Regional Rate Box A'),
|
||||||
(VARIABLE, "Variable")
|
(REGIONAL_RATE_BOX_B, 'Regional Rate Box B'),
|
||||||
|
(VARIABLE, 'Variable')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
"name": "Save 10%: Valid",
|
"name": "Save 10%: Valid",
|
||||||
"code": "MAY2022",
|
"code": "MAY2022",
|
||||||
"valid_from": "2022-05-01T06:00:00Z",
|
"valid_from": "2022-05-01T06:00:00Z",
|
||||||
"valid_to": "2022-05-31T06:00:00Z",
|
"valid_to": "2054-05-31T06:00:00Z",
|
||||||
"discount_value_type": "percentage",
|
"discount_value_type": "percentage",
|
||||||
"discount_value": "10.00",
|
"discount_value": "10.00",
|
||||||
"products": [],
|
"products": [],
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class AddressTests(StaticLiveServerTestCase):
|
|||||||
state_select.select_by_value('UT')
|
state_select.select_by_value('UT')
|
||||||
postal_code_input = self.browser.find_element_by_name('postal_code')
|
postal_code_input = self.browser.find_element_by_name('postal_code')
|
||||||
postal_code_input.send_keys('37461')
|
postal_code_input.send_keys('37461')
|
||||||
self.browser.find_element_by_xpath('//input[@value="Continue to Payment"]').click()
|
self.browser.find_element_by_xpath('//input[@value="Continue"]').click()
|
||||||
# try:
|
# try:
|
||||||
# WebDriverWait(self.browser, 4).until(
|
# WebDriverWait(self.browser, 4).until(
|
||||||
# EC.presence_of_element_located((By.CLASS_NAME, 'errorlist'))
|
# EC.presence_of_element_located((By.CLASS_NAME, 'errorlist'))
|
||||||
@ -77,7 +77,7 @@ class AddressTests(StaticLiveServerTestCase):
|
|||||||
state_select.select_by_value('AK')
|
state_select.select_by_value('AK')
|
||||||
postal_code_input = self.browser.find_element_by_name('postal_code')
|
postal_code_input = self.browser.find_element_by_name('postal_code')
|
||||||
postal_code_input.send_keys('99801')
|
postal_code_input.send_keys('99801')
|
||||||
self.browser.find_element_by_xpath('//input[@value="Continue to Payment"]').click()
|
self.browser.find_element_by_xpath('//input[@value="Continue"]').click()
|
||||||
# try:
|
# try:
|
||||||
# WebDriverWait(self.browser, 4).until(
|
# WebDriverWait(self.browser, 4).until(
|
||||||
# EC.presence_of_element_located((By.CLASS_NAME, 'errorlist'))
|
# EC.presence_of_element_located((By.CLASS_NAME, 'errorlist'))
|
||||||
|
|||||||
@ -85,7 +85,7 @@ class CouponTests(StaticLiveServerTestCase):
|
|||||||
postal_code_input = self.browser.find_element_by_name('postal_code')
|
postal_code_input = self.browser.find_element_by_name('postal_code')
|
||||||
postal_code_input.send_keys('84321')
|
postal_code_input.send_keys('84321')
|
||||||
self.browser.find_element_by_xpath(
|
self.browser.find_element_by_xpath(
|
||||||
'//input[@value="Continue to Payment"]'
|
'//input[@value="Continue"]'
|
||||||
).click()
|
).click()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -140,7 +140,7 @@ class CouponTests(StaticLiveServerTestCase):
|
|||||||
postal_code_input = self.browser.find_element_by_name('postal_code')
|
postal_code_input = self.browser.find_element_by_name('postal_code')
|
||||||
postal_code_input.send_keys('84321')
|
postal_code_input.send_keys('84321')
|
||||||
self.browser.find_element_by_xpath(
|
self.browser.find_element_by_xpath(
|
||||||
'//input[@value="Continue to Payment"]'
|
'//input[@value="Continue"]'
|
||||||
).click()
|
).click()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|||||||
@ -30,6 +30,7 @@ class Cart:
|
|||||||
self.request = request
|
self.request = request
|
||||||
self.session = request.session
|
self.session = request.session
|
||||||
self.coupon_code = self.session.get('coupon_code')
|
self.coupon_code = self.session.get('coupon_code')
|
||||||
|
self.container = self.session.get('shipping_container')
|
||||||
cart = self.session.get(settings.CART_SESSION_ID)
|
cart = self.session.get(settings.CART_SESSION_ID)
|
||||||
if not cart:
|
if not cart:
|
||||||
cart = self.session[settings.CART_SESSION_ID] = {}
|
cart = self.session[settings.CART_SESSION_ID] = {}
|
||||||
@ -109,20 +110,26 @@ class Cart:
|
|||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def get_shipping_box(self):
|
def get_shipping_box(self, container=None):
|
||||||
|
if container:
|
||||||
|
return container
|
||||||
|
|
||||||
|
if self.container:
|
||||||
|
return self.container
|
||||||
|
|
||||||
if len(self) > 6 and len(self) <= 10:
|
if len(self) > 6 and len(self) <= 10:
|
||||||
return ShippingContainer.LG_FLAT_RATE_BOX
|
return ShippingContainer.LG_FLAT_RATE_BOX
|
||||||
elif len(self) > 2 and len(self) <= 6:
|
elif len(self) > 3 and len(self) <= 6:
|
||||||
return ShippingContainer.REGIONAL_RATE_BOX_B
|
return ShippingContainer.REGIONAL_RATE_BOX_B
|
||||||
elif len(self) <= 2:
|
elif len(self) <= 3:
|
||||||
return ShippingContainer.REGIONAL_RATE_BOX_A
|
return ShippingContainer.REGIONAL_RATE_BOX_A
|
||||||
else:
|
else:
|
||||||
return ShippingContainer.VARIABLE
|
return ShippingContainer.VARIABLE
|
||||||
|
|
||||||
def get_shipping_cost(self):
|
def get_shipping_cost(self, container=None):
|
||||||
if len(self) > 0 and self.session.get("shipping_address"):
|
if len(self) > 0 and self.session.get("shipping_address"):
|
||||||
try:
|
try:
|
||||||
usps_rate_request = self.build_usps_rate_request()
|
usps_rate_request = self.build_usps_rate_request(container)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
return Decimal('0.00')
|
return Decimal('0.00')
|
||||||
usps = USPSApi(settings.USPS_USER_ID, test=True)
|
usps = USPSApi(settings.USPS_USER_ID, test=True)
|
||||||
@ -135,7 +142,7 @@ class Cart:
|
|||||||
)
|
)
|
||||||
|
|
||||||
logger.info(validation.result)
|
logger.info(validation.result)
|
||||||
if not 'Error' in validation.result['RateV4Response']['Package']:
|
if 'Error' not in validation.result['RateV4Response']['Package']:
|
||||||
rate = validation.result['RateV4Response']['Package']['Postage']['CommercialRate']
|
rate = validation.result['RateV4Response']['Package']['Postage']['CommercialRate']
|
||||||
else:
|
else:
|
||||||
logger.error("USPS Rate error")
|
logger.error("USPS Rate error")
|
||||||
@ -152,7 +159,7 @@ class Cart:
|
|||||||
pass
|
pass
|
||||||
self.session.modified = True
|
self.session.modified = True
|
||||||
|
|
||||||
def build_usps_rate_request(self):
|
def build_usps_rate_request(self, container=None):
|
||||||
return \
|
return \
|
||||||
{
|
{
|
||||||
'service': ShippingService.PRIORITY_COMMERCIAL,
|
'service': ShippingService.PRIORITY_COMMERCIAL,
|
||||||
@ -160,7 +167,7 @@ class Cart:
|
|||||||
'zip_destination': f'{self.session.get("shipping_address")["postal_code"]}',
|
'zip_destination': f'{self.session.get("shipping_address")["postal_code"]}',
|
||||||
'pounds': '0',
|
'pounds': '0',
|
||||||
'ounces': f'{self.get_total_weight()}',
|
'ounces': f'{self.get_total_weight()}',
|
||||||
'container': f'{self.get_shipping_box()}',
|
'container': f'{self.get_shipping_box(container)}',
|
||||||
'width': '',
|
'width': '',
|
||||||
'length': '',
|
'length': '',
|
||||||
'height': '',
|
'height': '',
|
||||||
@ -168,7 +175,7 @@ class Cart:
|
|||||||
'machinable': 'TRUE'
|
'machinable': 'TRUE'
|
||||||
}
|
}
|
||||||
|
|
||||||
def build_order_params(self):
|
def build_order_params(self, container=None):
|
||||||
return \
|
return \
|
||||||
{
|
{
|
||||||
'items': self,
|
'items': self,
|
||||||
@ -177,12 +184,14 @@ class Cart:
|
|||||||
'discount': f'{self.get_discount()}',
|
'discount': f'{self.get_discount()}',
|
||||||
'shipping_price': f'{self.get_shipping_cost()}',
|
'shipping_price': f'{self.get_shipping_cost()}',
|
||||||
'tax_total': '0',
|
'tax_total': '0',
|
||||||
'shipping_method': 'US POSTAL SERVICE',
|
'shipping_method': 'US POSTAL SERVICE ' + (
|
||||||
|
container if container else ''
|
||||||
|
),
|
||||||
'shipping_address': self.build_shipping_address(self.session.get('shipping_address')),
|
'shipping_address': self.build_shipping_address(self.session.get('shipping_address')),
|
||||||
}
|
}
|
||||||
|
|
||||||
def create_order(self):
|
def create_order(self, container=None):
|
||||||
params = self.build_order_params()
|
params = self.build_order_params(container)
|
||||||
logger.info(f'\nParams: {params}\n')
|
logger.info(f'\nParams: {params}\n')
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
response = CreateOrder().create_order(params, debug=True)
|
response = CreateOrder().create_order(params, debug=True)
|
||||||
|
|||||||
@ -11,7 +11,7 @@ from usps import USPSApi, Address
|
|||||||
from captcha.fields import CaptchaField
|
from captcha.fields import CaptchaField
|
||||||
|
|
||||||
from core.models import Order
|
from core.models import Order
|
||||||
from core import CoffeeGrind
|
from core import CoffeeGrind, ShippingContainer
|
||||||
|
|
||||||
from .tasks import contact_form_email
|
from .tasks import contact_form_email
|
||||||
|
|
||||||
@ -106,6 +106,18 @@ class AddressForm(forms.Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CheckoutShippingForm(forms.Form):
|
||||||
|
SHIPPING_CHOICES = [
|
||||||
|
(ShippingContainer.MD_FLAT_RATE_BOX, 'Flate Rate Box - Medium'),
|
||||||
|
(ShippingContainer.REGIONAL_RATE_BOX_B, 'Regional Rate Box B'),
|
||||||
|
]
|
||||||
|
|
||||||
|
shipping_method = forms.ChoiceField(
|
||||||
|
widget=forms.RadioSelect,
|
||||||
|
choices=SHIPPING_CHOICES
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OrderCreateForm(forms.ModelForm):
|
class OrderCreateForm(forms.ModelForm):
|
||||||
email = forms.CharField(widget=forms.HiddenInput())
|
email = forms.CharField(widget=forms.HiddenInput())
|
||||||
first_name = forms.CharField(widget=forms.HiddenInput())
|
first_name = forms.CharField(widget=forms.HiddenInput())
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{form.as_p}}
|
{{form.as_p}}
|
||||||
<p>
|
<p>
|
||||||
<input type="submit" value="Continue to Payment">
|
<input type="submit" value="Continue">
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
<p>We validate addresses with USPS, if you are having issues please contact us at <a href="mailto:support@ptcoffee.com">support@ptcoffee.com</a> or use the contact information found on our <a href="{% url 'storefront:contact' %}">contact</a> page.</p>
|
<p>We validate addresses with USPS, if you are having issues please contact us at <a href="mailto:support@ptcoffee.com">support@ptcoffee.com</a> or use the contact information found on our <a href="{% url 'storefront:contact' %}">contact</a> page.</p>
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block head_title %}Checkout | {% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h1>Checkout</h1>
|
||||||
|
</header>
|
||||||
|
<section>
|
||||||
|
<h3>Shipping Method</h3>
|
||||||
|
<form action="{% url 'storefront:checkout-shipping' %}" method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.non_field_errors }}
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{ form.shipping_method.label }}</legend>
|
||||||
|
{% for radio in form.shipping_method %}
|
||||||
|
<p>
|
||||||
|
<label for="{{ radio.id_for_label }}">
|
||||||
|
{{ radio.choice_label }}
|
||||||
|
{% if 'Flate Rate Box - Medium' in radio.choice_label %}
|
||||||
|
<strong>${{ MD_FLAT_RATE_BOX }}</strong>
|
||||||
|
{% elif 'Regional Rate Box B' in radio.choice_label %}
|
||||||
|
<strong>${{ REGIONAL_RATE_BOX_B }}</strong>
|
||||||
|
{% endif %}
|
||||||
|
</label>
|
||||||
|
{{ radio.tag }}
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
</fieldset>
|
||||||
|
<br>
|
||||||
|
<p>
|
||||||
|
<input type="submit" value="Continue to Payment">
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
{% endblock %}
|
||||||
@ -48,6 +48,11 @@ urlpatterns = [
|
|||||||
views.CheckoutAddressView.as_view(),
|
views.CheckoutAddressView.as_view(),
|
||||||
name='checkout-address',
|
name='checkout-address',
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
'checkout/shipping/',
|
||||||
|
views.CheckoutShippingView.as_view(),
|
||||||
|
name='checkout-shipping',
|
||||||
|
),
|
||||||
path('checkout/', views.OrderCreateView.as_view(), name='order-create'),
|
path('checkout/', views.OrderCreateView.as_view(), name='order-create'),
|
||||||
path('done/', views.PaymentDoneView.as_view(), name='payment-done'),
|
path('done/', views.PaymentDoneView.as_view(), name='payment-done'),
|
||||||
path(
|
path(
|
||||||
|
|||||||
@ -32,11 +32,11 @@ from accounts.forms import (
|
|||||||
)
|
)
|
||||||
from core.models import Product, Order, Transaction, OrderLine, Coupon
|
from core.models import Product, Order, Transaction, OrderLine, Coupon
|
||||||
from core.forms import ShippingMethodForm
|
from core.forms import ShippingMethodForm
|
||||||
from core import OrderStatus
|
from core import OrderStatus, ShippingContainer
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
AddToCartForm, UpdateCartItemForm, OrderCreateForm,
|
AddToCartForm, UpdateCartItemForm, OrderCreateForm,
|
||||||
AddressForm, CouponApplyForm, ContactForm
|
AddressForm, CouponApplyForm, ContactForm, CheckoutShippingForm,
|
||||||
)
|
)
|
||||||
from .cart import Cart
|
from .cart import Cart
|
||||||
from .payments import CaptureOrder
|
from .payments import CaptureOrder
|
||||||
@ -163,7 +163,7 @@ class ProductDetailView(FormMixin, DetailView):
|
|||||||
class CheckoutAddressView(FormView):
|
class CheckoutAddressView(FormView):
|
||||||
template_name = 'storefront/checkout_address.html'
|
template_name = 'storefront/checkout_address.html'
|
||||||
form_class = AddressForm
|
form_class = AddressForm
|
||||||
success_url = reverse_lazy('storefront:order-create')
|
success_url = reverse_lazy('storefront:checkout-shipping')
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
@ -212,6 +212,47 @@ class CheckoutAddressView(FormView):
|
|||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
class CheckoutShippingView(FormView):
|
||||||
|
template_name = 'storefront/checkout_shipping_form.html'
|
||||||
|
form_class = CheckoutShippingForm
|
||||||
|
success_url = reverse_lazy('storefront:order-create')
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
cart = Cart(request)
|
||||||
|
if len(cart) != 6:
|
||||||
|
if 'shipping_container' in self.request.session:
|
||||||
|
del self.request.session['shipping_container']
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
reverse('storefront:order-create')
|
||||||
|
)
|
||||||
|
|
||||||
|
if not self.request.session.get("shipping_address"):
|
||||||
|
messages.warning(request, 'Please add a shipping address.')
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
reverse('storefront:checkout-address')
|
||||||
|
)
|
||||||
|
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
cart = Cart(self.request)
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['MD_FLAT_RATE_BOX'] = cart.get_shipping_cost(
|
||||||
|
ShippingContainer.MD_FLAT_RATE_BOX
|
||||||
|
)
|
||||||
|
context['REGIONAL_RATE_BOX_B'] = cart.get_shipping_cost(
|
||||||
|
ShippingContainer.REGIONAL_RATE_BOX_B
|
||||||
|
)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
cleaned_data = form.cleaned_data
|
||||||
|
self.request.session['shipping_container'] = cleaned_data.get(
|
||||||
|
'shipping_method'
|
||||||
|
)
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class OrderCreateView(CreateView):
|
class OrderCreateView(CreateView):
|
||||||
model = Order
|
model = Order
|
||||||
template_name = 'storefront/order_form.html'
|
template_name = 'storefront/order_form.html'
|
||||||
@ -219,6 +260,10 @@ class OrderCreateView(CreateView):
|
|||||||
success_url = reverse_lazy('storefront:payment-done')
|
success_url = reverse_lazy('storefront:payment-done')
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
cart = Cart(request)
|
||||||
|
if len(cart) != 6 and 'shipping_container' in self.request.session:
|
||||||
|
del self.request.session['shipping_container']
|
||||||
|
|
||||||
if not self.request.session.get("shipping_address"):
|
if not self.request.session.get("shipping_address"):
|
||||||
messages.warning(request, 'Please add a shipping address.')
|
messages.warning(request, 'Please add a shipping address.')
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
@ -271,13 +316,14 @@ class OrderCreateView(CreateView):
|
|||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
cart = Cart(self.request)
|
cart = Cart(self.request)
|
||||||
shipping_address = self.request.session.get('shipping_address')
|
shipping_address = self.request.session.get('shipping_address')
|
||||||
|
shipping_container = self.request.session.get('shipping_container')
|
||||||
form.instance.customer, form.instance.shipping_address = get_or_create_customer(self.request, form, shipping_address)
|
form.instance.customer, form.instance.shipping_address = get_or_create_customer(self.request, form, shipping_address)
|
||||||
form.instance.status = OrderStatus.DRAFT
|
form.instance.status = OrderStatus.DRAFT
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
bulk_list = cart.build_bulk_list(self.object)
|
bulk_list = cart.build_bulk_list(self.object)
|
||||||
objs = OrderLine.objects.bulk_create(bulk_list)
|
objs = OrderLine.objects.bulk_create(bulk_list)
|
||||||
|
|
||||||
response = cart.create_order()
|
response = cart.create_order(shipping_container)
|
||||||
data = response.result.__dict__['_dict']
|
data = response.result.__dict__['_dict']
|
||||||
|
|
||||||
self.request.session['order_id'] = self.object.pk
|
self.request.session['order_id'] = self.object.pk
|
||||||
@ -339,8 +385,8 @@ class CustomerDetailView(UserPassesTestMixin, LoginRequiredMixin, DetailView):
|
|||||||
permission_denied_message = 'Not authorized.'
|
permission_denied_message = 'Not authorized.'
|
||||||
raise_exception = True
|
raise_exception = True
|
||||||
|
|
||||||
def get_context_data(self, *args, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(*args, **kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['order_list'] = Order.objects.without_drafts().filter(
|
context['order_list'] = Order.objects.without_drafts().filter(
|
||||||
customer=self.object
|
customer=self.object
|
||||||
).prefetch_related('lines')
|
).prefetch_related('lines')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user