# -*- coding: utf-8 -*- from django import forms from django.conf import settings from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError from django.forms.util import ErrorList from django.core.validators import validate_email, URLValidator #models from models import Seminar, CURRENCY, Statistic from country.models import Country from city.models import City from theme.models import Theme from organiser.models import Organiser from accounts.models import User from company.models import Company from service.models import Service #functions from functions.translate import fill_with_signal from functions.form_check import is_positive_integer from functions.files import check_tmp_files from functions.custom_fields import LocationWidget from functions.form_check import translit_with_separator from functions.admin_forms import AdminFilterForm class SeminarCreateForm(forms.Form): """ Create Seminar form for creating seminar __init__ uses for dynamic creates fields save function saves data in Seminar object. If it doesnt exist create new object """ currencies = [(item, item) for item in CURRENCY] data_begin = forms.DateTimeField(label='Дата и время начала') data_end = forms.DateTimeField(label='Дата и время оконочания') country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None) theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) #creates select input with empty choices cause it will be filled with ajax city = forms.ChoiceField(label='Город', choices=[('','')]) tag = forms.MultipleChoiceField(label='Теги', required=False) address = forms.CharField(label='Адрес', required=False, widget=LocationWidget)#google maps api web_page = forms.CharField(label='Веб страница', required=False) link = forms.CharField(label='Линк на регистрацию', required=False) foundation_year = forms.CharField(label='Год основания', required=False) members = forms.CharField(label='Посетители', required=False) visitors = forms.CharField(label='Участники', required=False) discount = forms.CharField(label='Cкидка(%)', required=False) quality_label = forms.MultipleChoiceField(label='Метки', required=False, choices=[('ufi', 'UFI'), ('rsva', 'РСВЯ'), ('exporating', 'ExpoRating')], widget=forms.CheckboxSelectMultiple()) # currency = forms.ChoiceField(label='Валюта', choices=currencies, required=False) tax = forms.BooleanField(label='Налог включен', initial=True, required=False) min_price = forms.CharField(label='Минимальная цена', required=False) max_price = forms.CharField(label='Максимальная цена', required=False) expohit = forms.BooleanField(label='Expohit', required=False) canceled = forms.BooleanField(label='Отменена', required=False) moved = forms.BooleanField(label='Перенесена', required=False) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) # seminar_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ create dynamical translated fields fields and fills select fields """ super(SeminarCreateForm, 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='Название', required=required) self.fields['main_title_%s' % code] = forms.CharField(label='Краткое описание', required=False, widget=CKEditorWidget) self.fields['programm_%s' % code] = forms.CharField(label='Описание', required=False, widget=CKEditorWidget) self.fields['discount_description_%s' % code] = forms.CharField(label='Условия и скидки', required=False, widget=CKEditorWidget) #meta data self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) #creates select inputs ind fill it #!service has bitfield. uncomment when country data will be filled #services = [(item.id, item.name) for item in Service.objects.all()] #self.fields['service'] = forms.MultipleChoiceField(label='Услуги', choices=services, required=False) def save(self, id=None): """ changes Seminar model object with id = id N/A add new Seminar model object usage: form.save(obj) - if change seminar form.save() - if add seminar """ data = self.cleaned_data #create new seminar object or get exists if not id: seminar = Seminar() else: seminar = Seminar.objects.get(id=id) seminar.theme.clear() seminar.tag.clear() #simple fields seminar.url = translit_with_separator(data['name_ru'].strip()).lower() seminar.data_begin = data['data_begin'] seminar.data_end = data['data_end'] seminar.link = data['link'] seminar.web_page= data['web_page'] seminar.foundation_year = data['foundation_year'] seminar.members = data['members'] seminar.visitors = data['visitors'] seminar.address = data['address'] # seminar.currency = data['currency'] seminar.tax = data['tax'] seminar.min_price = data['min_price'] seminar.max_price = data['max_price'] seminar.discount = data['discount'] seminar.expohit = data['expohit'] seminar.canceled = data['canceled'] seminar.moved = data['moved'] # generates bitfield flag = 0 if data['quality_label']: flag = reduce(lambda x,y: x|y, (getattr(Seminar.quality_label, item) for item in data['quality_label'])) seminar.quality_label = flag if data.get('country'): seminar.country = Country.objects.get(id=data['country'].id)#.id cause select uses queryset if data.get('city'): seminar.city = City.objects.get(id=data['city']) fill_with_signal(Seminar, seminar, data) #fill manytomany fields for item in data['theme']: seminar.theme.add(item.id)#.id cause select uses queryset for item in data['tag']: seminar.tag.add(item) seminar.save() #save files check_tmp_files(seminar, data['key']) return seminar def clean(self): id = self.cleaned_data.get('seminar_id') name_ru = self.cleaned_data.get('name_ru') seminar = Seminar.objects.filter(url=translit_with_separator(name_ru)) if seminar and str(seminar[0].id) != id: msg = 'Семинар с таким названием уже существует' self._errors['name_ru'] = ErrorList([msg]) del self.cleaned_data['name_ru'] return self.cleaned_data def clean_web_page(self): """ checking web_page """ cleaned_data = super(SeminarCreateForm, 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_link(self): """ checking link """ cleaned_data = super(SeminarCreateForm, self).clean() link = cleaned_data.get('link') if not link: return '' validate = URLValidator() try: validate(link) except(forms.ValidationError),e: raise forms.ValidationError(e.messages[0]) return link def clean_foundation_year(self): """ checking foundation_year """ cleaned_data = super(SeminarCreateForm, self).clean() foundation_year = cleaned_data.get('foundation_year').strip() return is_positive_integer(foundation_year) def clean_visitors(self): """ checking visitors """ cleaned_data = super(SeminarCreateForm, self).clean() visitors = cleaned_data.get('visitors').strip() return is_positive_integer(visitors) def clean_members(self): """ checking members """ cleaned_data = super(SeminarCreateForm, self).clean() members = cleaned_data.get('members').strip() return is_positive_integer(members) def clean_min_price(self): """ checking min_price """ cleaned_data = super(SeminarCreateForm, self).clean() min_price = cleaned_data.get('min_price').strip() return is_positive_integer(min_price) def clean_max_price(self): """ checking max_price """ cleaned_data = super(SeminarCreateForm, self).clean() max_price = cleaned_data.get('max_price').strip() return is_positive_integer(max_price) def clean_discount(self): """ checking discount """ cleaned_data = super(SeminarCreateForm, self).clean() discount = cleaned_data.get('discount').strip() return is_positive_integer(discount) class SeminarChangeForm(SeminarCreateForm): """ add some fields to SeminarCreateForm """ organiser = forms.ModelMultipleChoiceField(label='Организаторы', queryset=Organiser.objects.all(), required=False) company = forms.ModelMultipleChoiceField(label='Компании', queryset=Company.objects.all(), required=False) users = forms.ModelMultipleChoiceField(label='Пользователи', queryset=User.objects.all(), required=False) class SeminarDeleteForm(forms.ModelForm): url = forms.CharField(widget=forms.HiddenInput()) class Meta: model = Seminar fields = ('url',) class StatisticForm(forms.ModelForm): year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'})) visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) class Meta: model = Statistic exclude = ('seminar') 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) class SeminarFilterForm(AdminFilterForm): model = Seminar