You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
12 KiB
310 lines
12 KiB
from crispy_forms.helper import FormHelper
|
|
from crispy_forms.layout import Layout, Field, Div, HTML, Hidden, Fieldset, Submit
|
|
from django import forms
|
|
from django.conf import settings
|
|
from django.core.exceptions import ValidationError
|
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
|
from django.forms import ALL_FIELDS, formset_factory
|
|
from django.urls import reverse_lazy
|
|
|
|
from cart.models import (
|
|
Buying, BUYING_STATUS_IN_CART, Offer, SupplyType, SupplyTarget, Discount, Order
|
|
)
|
|
from cart.tasks import send_user_order_notification, send_admin_order_notification
|
|
from contact_us.mixins import RequestNotifiable
|
|
from core.forms import QueryFormBase
|
|
from core.models import City
|
|
from core.utils import parse_path
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from products.models import Product
|
|
|
|
|
|
class CartAddInlineForm(forms.ModelForm):
|
|
form_action = {'viewname': 'cart:add', 'kwargs': {}}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.helper = FormHelper()
|
|
self.helper.form_method = 'post'
|
|
self.helper.form_action = reverse_lazy(**self.form_action)
|
|
self.helper.layout = Layout(
|
|
Field('offer'),
|
|
Field('amount'),
|
|
Div(
|
|
Submit('add', value=_('Купить')),
|
|
css_class='catalog__btn'
|
|
)
|
|
)
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def clean_amount(self):
|
|
amount = self.cleaned_data['amount']
|
|
offer = self.cleaned_data['offer']
|
|
if amount > offer.amount:
|
|
raise ValidationError('Колличество товара указано больше доступного')
|
|
elif amount <= 0:
|
|
raise ValidationError('Укажите колличество товара больше 0')
|
|
return amount
|
|
|
|
def save(self, cart, user, commit=True):
|
|
offer = Offer.active.get(self.offer)
|
|
self.instance.user = user
|
|
self.instance.offer = offer
|
|
self.instance.amount = self.cart[offer.product.id]['quantity']
|
|
self.instance.total_price = offer.product * self.cart[offer.product.id]['quantity']
|
|
return super().save(commit)
|
|
|
|
class Meta:
|
|
model = Buying
|
|
fields = ('offer', 'amount',)
|
|
widgets = {
|
|
'offer': forms.HiddenInput(),
|
|
'amount': forms.HiddenInput()
|
|
}
|
|
|
|
|
|
class CartRemoveBuyingForm(forms.ModelForm):
|
|
form_action = {'viewname': 'cart:remove', 'kwargs': {}}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.helper = FormHelper()
|
|
self.helper.form_method = 'post'
|
|
self.helper.form_action = reverse_lazy(**self.form_action)
|
|
self.helper.layout = Layout(
|
|
Field('offer'),
|
|
Div(
|
|
Submit('cancel', value=_('Убрать')),
|
|
css_class='catalog__btn'
|
|
)
|
|
)
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
class Meta:
|
|
model = Buying
|
|
fields = ('offer',)
|
|
widgets = {
|
|
'offer': forms.HiddenInput()
|
|
}
|
|
|
|
|
|
class CartCheckoutBuyingForm(forms.Form):
|
|
order = forms.Field()
|
|
offer = forms.Field()
|
|
amount = forms.IntegerField()
|
|
bonus_points = forms.IntegerField()
|
|
|
|
def get_initial_for_field(self, field, field_name):
|
|
if field_name == 'offer':
|
|
field = Offer.active.get(product_id=self.initia[field_name])
|
|
elif field_name == 'order':
|
|
field = Order.objects.get(order_code=self.initial[field_name])
|
|
elif field_name == 'amount' or field_name == 'bonus_points':
|
|
field.value = self.initial[field_name]
|
|
return super().get_initial_for_field(field, field_name)
|
|
|
|
def save(self, user):
|
|
buying = Buying()
|
|
buying.user = user
|
|
buying.offer = self.offer
|
|
buying.order = self.order
|
|
buying.bonus_points = self.bonus_points
|
|
buying.amount = self.amount
|
|
buying.total_price = self.offer.get_price_with_discount * self.amount
|
|
buying.save()
|
|
return buying
|
|
|
|
|
|
class CartCheckoutForm(RequestNotifiable, forms.ModelForm):
|
|
form_action = {'viewname': 'cart:confirm', 'kwargs': {}}
|
|
field_template = 'bootstrap/forms/cart_checkout.html'
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.helper = FormHelper()
|
|
self.helper.form_method = 'post'
|
|
self.helper.form_action = reverse_lazy(**self.form_action)
|
|
self.helper.layout = Layout(
|
|
Field('customer_name', css_class="order__input", template=self.field_template),
|
|
Field('customer_email', css_class="order__input", template=self.field_template),
|
|
Field('customer_user', css_class="order__input", template=self.field_template),
|
|
Field('phone', css_class="order__input", template=self.field_template),
|
|
Field('customer_address', css_class="order__input", template=self.field_template),
|
|
Field('city', css_class="order__input", template=self.field_template),
|
|
Field('comment', css_class="order__input", template=self.field_template),
|
|
Div(
|
|
Submit('checkout', value=_('Подтвердить'), style="margin: 0 auto;"),
|
|
css_class='catalog__btn'
|
|
)
|
|
)
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def save(self, commit=True):
|
|
if not City.objects.filter(name=self.cleaned_data['city']).exists():
|
|
city = City()
|
|
city.name = self.cleaned_data['city']
|
|
city.save()
|
|
self.instance.city = city
|
|
return super().save(commit)
|
|
|
|
def send_order_invoice(self, request):
|
|
return send_user_order_notification.delay(self.instance.id, request)
|
|
|
|
def send_order_request(self, request):
|
|
context = {
|
|
'from_email': settings.DEFAULT_FROM_EMAIL,
|
|
'recipients': (settings.DEFAULT_FROM_EMAIL,),
|
|
'email': {
|
|
'subject': _('У вас новый заказ'),
|
|
'order': self.instance,
|
|
},
|
|
'send_at_date': self.instance.create_at,
|
|
|
|
}
|
|
return send_admin_order_notification.delay(context)
|
|
|
|
class Meta:
|
|
model = Order
|
|
fields = (
|
|
'customer_name', 'customer_email', 'phone', 'customer_address', 'city', 'comment'
|
|
)
|
|
widgets = {
|
|
'city': forms.TextInput()
|
|
}
|
|
|
|
|
|
class ProductOfferPriceFilterForm(QueryFormBase):
|
|
min_price = 0
|
|
max_price = 9999
|
|
price = forms.IntegerField(min_value=0, max_value=0)
|
|
field_template = 'bootstrap/forms/product_filter.html'
|
|
title = _('Цена')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.form_method = 'get'
|
|
self.helper.layout = Layout(
|
|
Div(HTML(self.title), css_class='category__title left-menu__price-item'),
|
|
Field('price', template=self.field_template)
|
|
)
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.helper.form_action = reverse_lazy(**self.form_action)
|
|
|
|
self.init_price_bounders()
|
|
self.init_field_params()
|
|
|
|
def init_price_bounders(self):
|
|
if Offer.active.exists():
|
|
off_qs = Offer.active
|
|
category_instance = ''
|
|
if self.form_action.get('kwargs', None):
|
|
category_instance = parse_path(self.form_action.get('kwargs').get('path', ''))
|
|
|
|
off_qs = Offer.active.filter(product__parent__name=category_instance,
|
|
product__name__icontains=self.query_params.get('name', ''))
|
|
if off_qs.exists():
|
|
self.min_price = round(off_qs.order_by('price').only('price').first().price, 0)
|
|
self.max_price = round(off_qs.order_by('-price').only('price').first().price, 0)
|
|
|
|
def init_field_params(self):
|
|
for field in self.fields:
|
|
if field == 'price':
|
|
self.fields[field].validators = [
|
|
MaxValueValidator(self.max_price),
|
|
MinValueValidator(self.min_price)
|
|
]
|
|
|
|
def get_initial_for_field(self, field, field_name):
|
|
return super().get_initial_for_field(field, field_name)
|
|
|
|
|
|
class ProductOfferSupplyTypeFilterForm(QueryFormBase):
|
|
supply_type = forms.ChoiceField()
|
|
|
|
field_template = 'bootstrap/forms/product_filter.html'
|
|
title = _('Тип поставки')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.helper = FormHelper()
|
|
self.helper.form_method = 'get'
|
|
self.helper.layout = Layout(
|
|
Div(HTML(self.title), css_class='category__title'),
|
|
Field('supply_type', template=self.field_template)
|
|
)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.helper.form_action = reverse_lazy(**self.form_action)
|
|
|
|
def get_initial_for_field(self, field, field_name):
|
|
if field_name == 'supply_type':
|
|
sup_typ_qs = SupplyType.objects
|
|
category_instance = ''
|
|
if self.form_action.get('kwargs', None):
|
|
category_instance = parse_path(self.form_action.get('kwargs').get('path', ''))
|
|
|
|
off_qs = Offer.active.filter(product__parent__name=category_instance,
|
|
product__name__icontains=self.query_params.get('name', ''))
|
|
if off_qs.count():
|
|
sup_typ_qs = sup_typ_qs.filter(offer__pk__in=off_qs.all())
|
|
|
|
return sup_typ_qs.distinct('name').only('name', 'slug')
|
|
return super().get_initial_for_field(field, field_name)
|
|
|
|
|
|
class ProductOfferSupplyTargetFilterForm(QueryFormBase):
|
|
supply_target = forms.ChoiceField()
|
|
|
|
field_template = 'bootstrap/forms/product_filter.html'
|
|
title = _('Назначение')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.helper = FormHelper()
|
|
self.helper.form_method = 'get'
|
|
self.helper.layout = Layout(
|
|
Div(HTML(self.title), css_class='category__title'),
|
|
Field('supply_target', template=self.field_template)
|
|
)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.helper.form_action = reverse_lazy(**self.form_action)
|
|
|
|
def get_initial_for_field(self, field, field_name):
|
|
if field_name == 'supply_target':
|
|
sup_tar_qs = SupplyTarget.objects
|
|
category_instance = ''
|
|
if self.form_action.get('kwargs', None):
|
|
category_instance = parse_path(self.form_action.get('kwargs').get('path', ''))
|
|
|
|
off_qs = Offer.active.filter(product__parent__name=category_instance,
|
|
product__name__icontains=self.query_params.get('name', ''))
|
|
|
|
if off_qs.count():
|
|
sup_tar_qs = sup_tar_qs.filter(product__pk__in=off_qs.all())
|
|
|
|
return sup_tar_qs.distinct('name').only('name', 'slug')
|
|
return super().get_initial_for_field(field, field_name)
|
|
|
|
|
|
# @TODO: NOT IMPLEMENTED ON THE FRONT END. TEST BEFORE PRODUCTION
|
|
class DiscountForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Discount
|
|
fields = ('code',)
|
|
|
|
|
|
class OrderCreateForm(forms.ModelForm):
|
|
customer_name = forms.CharField(max_length=100, required=True, label='Customer_name',
|
|
widget=forms.TextInput(attrs={'placeholder': 'Ф.И.О.'}))
|
|
customer_phone = forms.CharField(required=True, label='Customer_phone',
|
|
widget=forms.TextInput(attrs={'placeholder': 'номер телефона'}))
|
|
customer_email = forms.EmailField(required=True, label='Customer_email',
|
|
widget=forms.TextInput(attrs={'placeholder': 'e-mail'}))
|
|
city = forms.CharField(max_length=100, label='City', widget=forms.TextInput(attrs={'placeholder': 'город'}))
|
|
|
|
class Meta:
|
|
model = Order
|
|
exclude = ('status',)
|
|
|