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.
 
 
 
 
 
 

622 lines
29 KiB

# -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
from ckeditor.widgets import CKEditorWidget
from django.forms.util import ErrorList
from django.core.validators import validate_email, URLValidator
from django.utils.translation import ugettext as _
#models
from models import Exposition, TimeTable, TmpTimeTable, AUDIENCE1, CURRENCY, Statistic, BIT_AUDIENCE
from theme.models import Tag
from country.models import Country
from theme.models import Theme
from organiser.models import Organiser
from city.models import City
from place_exposition.models import PlaceExposition
#functions
from functions.translate import fill_with_signal
from functions.form_check import is_positive_integer
from functions.form_check import translit_with_separator
from settings.settings import date_formats
from functions.admin_forms import AdminFilterForm, EventsAdminFilterFormMixin
places = [(item.id, item.name) for item in PlaceExposition.objects.language().all()]
places.insert(0,('', 'Не выбрано'))
class ExpositionCreateForm(forms.Form):
"""
Create Exposition form for creating exposition
__init__ uses for dynamic creates fields
save function saves data in Exposition object. If it doesnt exist create new object
"""
PERIODIC = ((0, _(u'Не выбрано')), (1.0, _(u'Ежегодно')), (2.0, _(u'2 раза в год')), (3.0, _(u'3 раза в год')),
(4.0, _(u'4 раза в год')), (5.0, _(u'5 раз в год')), (0.5, _(u'Раз в 2 года')),(0.33, _(u'Раз в 3 года')),
(0.25, _(u'Раз в 4 года')), (0.2, _(u'Раз в 5 лет')))
public = [(item1, item2) for item1, item2 in BIT_AUDIENCE]
currencies = [(item, item) for item in CURRENCY]
data_begin = forms.DateField(label=_(u'Дата начала'), input_formats=['%Y-%m-%d', '%d.%m.%Y'])
data_end = forms.DateField(label=_(u'Дата окончания'), input_formats=['%Y-%m-%d', '%d.%m.%Y'])
logo = forms.ImageField(label=_('Logo'), required=False)
#organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
# choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
org = forms.CharField(required=False, label=_(u'Организатор'))
#company = forms.MultipleChoiceField(label=u'Компании', required=False,
# choices=[(item.id, item.name) for item in Company.objects.language().all()] )
country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.all()])
theme = forms.MultipleChoiceField(
label=_(u'Тематики'),
choices=[(item.id, item.name) for item in Theme.objects.language().filter(types=Theme.types.exposition)])
place = forms.ChoiceField(label=_(u'Место проведения'), required=False,
choices=places)
place_alt = forms.CharField(required=False, label=_(u'Альтернативное место'))
#creates select input with empty choices cause it will be filled with ajax
city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput())
tag = forms.CharField(label=_(u'Теги'), widget=forms.HiddenInput(), required=False)
periodic = forms.ChoiceField(label=_(u'Периодичность'), choices=PERIODIC, required=False)
audience = forms.MultipleChoiceField(label=_(u'Аудитория'), choices=public, initial='', required=False)
web_page = forms.CharField(label=_(u'Веб страница'), required=False)
registration_link = forms.CharField(label=_(u'Ссылка на регистрацию'), required=False)
foundation_year = forms.CharField(label=_(u'Год основания'), required=False)
members = forms.CharField(label=_(u'Участники'), required=False)
visitors = forms.CharField(label=_(u'Посетители'), required=False)
min_area = forms.CharField(label=_(u'Минимальная площадь'), required=False)
discount = forms.CharField(label=_(u'Cкидка(%)'), required=False)
area = forms.CharField(label=_(u'Площадь'), required=False)
quality_label = forms.MultipleChoiceField(label=_(u'Метки'), required=False,
choices=[('ufi', 'UFI'), ('rsva', 'РСВЯ'), ('exporating', 'ExpoRating')],
widget=forms.CheckboxSelectMultiple())
#
currency = forms.ChoiceField(label=_(u'Валюта'), choices=currencies, required=False)
application_deadline = forms.DateField(label=_(u'Срок подачи стенда'),input_formats=['%Y-%m-%d', '%d.%m.%Y'], required=False)
min_stand_size = forms.CharField(label=_(u'Минимальный размер стенда'), required=False)
price_catalog = forms.CharField(label=_(u'Цена за каталог'), required=False)
tax = forms.BooleanField(label=_(u'Налог включен'), initial=True, required=False)
min_closed_area = forms.CharField(label=_(u'Минимальная цена закрытой НЕ оборудованной площади'), required=False)
max_closed_area = forms.CharField(label=_(u'Максимальная цена закрытой НЕ оборудованной площади'), required=False)
min_closed_equipped_area = forms.CharField(label=_(u'Минимальная цена закрытой оборудованной площади'), required=False)
max_closed_equipped_area = forms.CharField(label=_(u'Максимальная цена закрытой оборудованной площади'), required=False)
min_open_area = forms.CharField(label=_(u'Минимальная цена открытой площади'), required=False)
max_open_area = forms.CharField(label=_(u'Максимальная цена открытой площади'), required=False)
registration_payment = forms.CharField(label=_(u'Регистрационны взнос'), required=False)
expohit = forms.BooleanField(label=_(u'Expohit'), required=False)
canceled = forms.BooleanField(label=_(u'Отменена'), required=False)
moved = forms.BooleanField(label=_(u'Перенесена'), required=False)
#field for comparing tmp files
key = forms.CharField(required=False, widget=forms.HiddenInput())
#
exposition_id = forms.CharField(required=False, widget=forms.HiddenInput())
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
"""
super(ExpositionCreateForm, self).__init__(*args, **kwargs)
#creates translated forms example: name_ru, name_en
# len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs
if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES):
# uses enumerate for detect iteration number
# first iteration is a default lang so it required fields
required = True if lid == 0 else False
self.fields['name_%s' % code] = forms.CharField(label=_(u'Название'), required=required,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['main_title_%s' % code] = forms.CharField(label=_(u'Краткое описание'),
required=False, widget=CKEditorWidget)
self.fields['description_%s' % code] = forms.CharField(label=_(u'Описание'),
required=False, widget=CKEditorWidget)
self.fields['time_%s' % code] = forms.CharField(label=_(u'Время работы'),
required=False, widget=CKEditorWidget)
self.fields['price_day_%s' % code] = forms.CharField(label=_(u'Стоимость билета 1 день'), required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['price_all_%s' % code] = forms.CharField(label=_(u'Стоимость билета все дни'), required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['price_day_bar_%s' % code] = forms.CharField(label=_(u'Стоимость на стойке 1 день'), required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['price_all_bar_%s' % code] = forms.CharField(label=_(u'Стоимость на стойке все дни'), required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['products_%s' % code] = forms.CharField(label=_(u'Экспонируемые продукты'),
required=False, widget=CKEditorWidget)
self.fields['discount_description_%s' % code] = forms.CharField(label=_(u'Описание скидки'),
required=False, widget=CKEditorWidget)
self.fields['stat_countries_%s' % code] = forms.CharField(label=_(u'Участвующие страны'),
required=False, widget=CKEditorWidget)
self.fields['pre_condition_%s' % code] = forms.CharField(label=_(u'Условия предварительной регистрации'),required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['stand_condition_%s' % code] = forms.CharField(label=_(u'Условия регистрации на стойке'),required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['visit_note_%s' % code] = forms.CharField(label=_(u'Примечание по посещению'),required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['participation_note_%s' % code] = forms.CharField(label=_(u'Примечание по участии'),required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
#meta data
self.fields['title_%s' % code] = forms.CharField(label=_(u'Meta title'), required=False, max_length=255,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['keywords_%s' % code] = forms.CharField(label=_(u'Meta keywords'), required=False, max_length=255,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Meta description'), required=False, max_length=255,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
def save(self, obj=None):
"""
change Exposition model object with id = id
N/A add new Exposition model object
usage: form.save(obj) - if change exposition
form.save() - if add exposition
"""
data = self.cleaned_data
if not obj:
exposition = Exposition()
else:
exposition = obj
exposition.theme.clear()
exposition.organiser.clear()
if data.get('tag'):
exposition.tag.clear()
#simple fields
if not getattr(exposition, 'url'):
exposition.url = translit_with_separator(data['name_ru'].strip()).lower()
if data.get('logo'):
exposition.logo = data['logo']
exposition.org = data['org']
exposition.data_begin = data['data_begin']
exposition.data_end = data['data_end']
exposition.periodic = data['periodic']
exposition.web_page= data['web_page']
exposition.registration_link = data['registration_link']
exposition.foundation_year = data['foundation_year']
exposition.members = data['members']
exposition.visitors = data['visitors']
exposition.area = data['area']
exposition.min_area = data['min_area']
exposition.currency = data['currency']
exposition.application_deadline = data['application_deadline']
exposition.min_stand_size = data['min_stand_size']
exposition.price_catalog = data['price_catalog']
exposition.tax = data['tax']
exposition.min_closed_area = data['min_closed_area']
exposition.max_closed_area = data['max_closed_area']
exposition.min_closed_equipped_area = data['min_closed_equipped_area']
exposition.max_closed_equipped_area = data['max_closed_equipped_area']
exposition.min_open_area = data['min_open_area']
exposition.max_open_area = data['max_open_area']
exposition.registration_payment = data['registration_payment']
exposition.discount = data['discount']
exposition.expohit = data['expohit']
exposition.canceled = data['canceled']
exposition.moved = data['moved']
# generates bitfield
quality = 0
if data['quality_label']:
quality = reduce(lambda x,y: x|y, (getattr(Exposition.quality_label, item) for item in data['quality_label']))
exposition.quality_label = quality
audience = 0
if data['audience']:
audience = reduce(lambda x,y: x|y, (getattr(Exposition.audience, item) for item in data['audience']))
exposition.audience = audience
exposition.country = Country.objects.get(id=data['country'])
exposition.city = City.objects.get(id=data['city'])
if data.get('place'):
exposition.place = PlaceExposition.objects.get(id=data['place'])
else:
exposition.place = None
exposition.place_alt = data['place_alt']
# fill translated fields and save object
fill_with_signal(Exposition, exposition, data)
#fill manytomany fields
exposition.theme.add(*data['theme'])
exposition.tag.add(*Tag.objects.filter(id__in=data['tag']))
exposition.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', [])))
#exposition.company.add(*Company.objects.filter(id__in=data.get('company', [])))
exposition.save()
return exposition
def clean(self):
id = self.cleaned_data.get('exposition_id')
name_ru = self.cleaned_data.get('name_ru')
exposition = Exposition.objects.filter(url=translit_with_separator(name_ru))
if exposition and str(exposition[0].id) != id:
msg = _(u'Выставка с таким названием уже существует')
self._errors['name_ru'] = ErrorList([msg])
del self.cleaned_data['name_ru']
return self.cleaned_data
def clean_tag(self):
tags = self.cleaned_data.get('tag')
if tags:
res = []
for id in tags.split(','):
try:
res.append(int(id))
except:
continue
return res
else:
return []
def clean_web_page(self):
"""
checking web_page
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
web_page = cleaned_data.get('web_page')
if not web_page:
return ''
validate = URLValidator()
try:
validate(web_page)
except(forms.ValidationError),e:
raise forms.ValidationError(e.messages[0])
return web_page
def clean_registration_link(self):
"""
checking web_page
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
registration_link = cleaned_data.get('registration_link')
if not registration_link:
return ''
validate = URLValidator()
try:
validate(registration_link)
except(forms.ValidationError),e:
raise forms.ValidationError(e.messages[0])
return registration_link
def clean_area(self):
"""
checking foundation_year
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
area = cleaned_data.get('area').strip()
return is_positive_integer(area)
def clean_foundation_year(self):
"""
checking foundation_year
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
foundation_year = cleaned_data.get('foundation_year').strip()
return is_positive_integer(foundation_year)
def clean_price_day(self):
"""
checking price_day
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
price_day = cleaned_data.get('price_day').strip()
return is_positive_integer(price_day)
def clean_price_all(self):
"""
checking price_all
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
price_all = cleaned_data.get('price_all').strip()
return is_positive_integer(price_all)
def clean_price_day_bar(self):
"""
checking price_day_bar
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
price_day_bar = cleaned_data.get('price_day_bar').strip()
return is_positive_integer(price_day_bar)
def clean_price_all_bar(self):
"""
checking price_all_bar
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
price_all_bar = cleaned_data.get('price_all_bar').strip()
return is_positive_integer(price_all_bar)
def clean_min_stand_size(self):
"""
checking min_stand_size
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
min_stand_size = cleaned_data.get('min_stand_size').strip()
return is_positive_integer(min_stand_size)
def clean_price_catalog(self):
"""
checking price_catalog
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
price_catalog = cleaned_data.get('price_catalog').strip()
return is_positive_integer(price_catalog)
def clean_visitors(self):
"""
checking visitors
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
visitors = cleaned_data.get('visitors').strip()
return is_positive_integer(visitors)
def clean_members(self):
"""
checking members
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
members = cleaned_data.get('members').strip()
return is_positive_integer(members)
def clean_min_area(self):
"""
checking min_area
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
min_area = cleaned_data.get('min_area').strip()
return is_positive_integer(min_area)
def clean_min_closed_area(self):
"""
checking min_closed_area
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
min_closed_area = cleaned_data.get('min_closed_area').strip()
return is_positive_integer(min_closed_area)
#
def clean_max_closed_area(self):
"""
checking max_closed_area
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
max_closed_area = cleaned_data.get('max_closed_area').strip()
return is_positive_integer(max_closed_area)
def clean_min_closed_equipped_area(self):
"""
checking min_closed_equipped_area
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
min_closed_equipped_area = cleaned_data.get('min_closed_equipped_area').strip()
return is_positive_integer(min_closed_equipped_area)
def clean_max_closed_equipped_area(self):
"""
checking max_closed_equipped_area
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
max_closed_equipped_area = cleaned_data.get('max_closed_equipped_area').strip()
return is_positive_integer(max_closed_equipped_area)
def clean_min_open_area(self):
"""
checking min_open_area
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
min_open_area = cleaned_data.get('min_open_area').strip()
return is_positive_integer(min_open_area)
def clean_max_open_area(self):
"""
checking max_open_area
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
max_open_area = cleaned_data.get('max_open_area').strip()
return is_positive_integer(max_open_area)
def clean_registration_payment(self):
"""
checking registration_payment
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
registration_payment = cleaned_data.get('registration_payment').strip()
return is_positive_integer(registration_payment)
def clean_discount(self):
"""
checking discount
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
discount = cleaned_data.get('discount').strip()
return is_positive_integer(discount)
class ExpositionDeleteForm(forms.ModelForm):
url = forms.CharField(widget=forms.HiddenInput())
class Meta:
model = Exposition
fields = ('url',)
class StatisticForm(forms.Form):
year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), label=_(u'Год'))
visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label=_(u'Посетители'))
members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label=_(u'Участники'))
area = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label=_(u'Площадь'))
countries_number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label=_(u'Число стран'))
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
"""
super(StatisticForm, self).__init__(*args, **kwargs)
#creates translated forms example: name_ru, name_en
# len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs
if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES):
# uses enumerate for detect iteration number
# first iteration is a default lang so it required fields
required = True if lid == 0 else False
self.fields['countries_%s' % code] = forms.CharField(label=_(u'Участвующие страны'),
required=False,
widget=forms.TextInput(attrs={'style':'width: 250px'}))
def save(self, exposition=None):
data = self.cleaned_data
if not exposition:
return None
else:
stat = Statistic()
# simple fields
stat.exposition = exposition
stat.year = data['year']
stat.visitors = data.get('visitors')
stat.members = data.get('members')
stat.area = data.get('area')
stat.countries_number = data.get('countries_number')
fill_with_signal(Statistic, stat, data)
return stat
def clean_year(self):
cleaned_data = super(StatisticForm, self).clean()
year = cleaned_data.get('year').strip()
return is_positive_integer(year)
def clean_members(self):
cleaned_data = super(StatisticForm, self).clean()
members = cleaned_data.get('members').strip()
return is_positive_integer(members)
def clean_visitors(self):
cleaned_data = super(StatisticForm, self).clean()
visitors = cleaned_data.get('visitors').strip()
return is_positive_integer(visitors)
def clean_countries_number(self):
cleaned_data = super(StatisticForm, self).clean()
countries_number = cleaned_data.get('countries_number').strip()
return is_positive_integer(countries_number)
from functions.files import check_tmp_timetables
class TimeTableForm(forms.Form):
begin = forms.DateTimeField(label=_(u'Время начала'), input_formats=date_formats,
widget=forms.TextInput(attrs={'style':'width: 150px'}))
end = forms.DateTimeField(label=_(u'Время окончания'), input_formats=date_formats,
widget=forms.TextInput(attrs={'style':'width: 150px'}))
timetable_organiser = forms.ChoiceField(label=_(u'Организатор'), required=False,
choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
and fills select fields
"""
super(TimeTableForm, self).__init__(*args, **kwargs)
#creates translated forms example: name_ru, name_en
# len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs
if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES):
# uses enumerate for detect iteration number
# first iteration is a default lang so it required fields
required = True if lid == 0 else False
self.fields['name_%s' % code] = forms.CharField(label=_(u'Название программы'), required=required,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['programe_%s' % code] = forms.CharField(label=_(u'Программа'), required=False,
widget=CKEditorWidget)
self.fields['speaker_%s' % code] = forms.CharField(label=_(u'Организатор'), required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['place_%s' % code] = forms.CharField(label=_(u'Место проведения'), required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
def save(self,exposition=None):
data = self.cleaned_data
if not exposition:
return None
else:
timetable = TimeTable()
# simple fields
if data.get('timetable_organiser'):
timetable.timetable_organiser_id = data['timetable_organiser']
timetable.exposition = exposition
timetable.begin = data.get('begin')
timetable.end = data.get('end')
if not exposition:
fill_with_signal(TmpTimeTable, timetable, data)
else:
fill_with_signal(TimeTable, timetable, data)
return timetable
monthes = [('', ''),
(1, _(u'Январь')), (2, _(u'Февраль')), (3, _(u'Март')), (4, _(u'Апрель')),
(5, _(u'Май')), (6, _(u'Июнь')), (7, _(u'Июль')), (8, _(u'Август')),
(9, _(u'Сентябрь')), (10, _(u'Октябрь')), (11, _(u'Ноябрь')), (12, _(u'Декабрь'))]
class ExpositionFilterForm(EventsAdminFilterFormMixin, AdminFilterForm):
model = Exposition
country = forms.MultipleChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.all()],
required=False)
#city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False)
year = forms.CharField(label=_(u'Год'), required=False)
month = forms.ChoiceField(label=_(u'Месяц'),choices=[(item[0], item[1]) for item in monthes], required=False)
def filter(self):
data = self.cleaned_data
qs = super(ExpositionFilterForm, self).filter()
exact_name = data['exact_name']
if exact_name:
return self.model.objects.filter(translations__name=exact_name).distinct()
country = data['country']
# city = data['city']
year = data['year']
month = data['month']
if country:
qs = qs.filter(country__in=country)
# if city:
# qs = qs.filter(city__in=city)
if year:
qs = qs.filter(data_begin__year=year)
if month:
qs = qs.filter(data_begin__month=month)
return qs