# -*- 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 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(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