# -*- coding: utf-8 -*- from django.conf import settings from django.contrib.contenttypes import generic from django.core.urlresolvers import reverse_lazy from django.db import models from django.db.models.signals import post_save, pre_save from django.utils import translation from django.utils.translation import ugettext as _ from bitfield import BitField from exposition.manager import ClientManager from functions.custom_fields import EnumField from functions.model_mixin import EventMixin, ExpoMixin from functions.models_methods import ExpoManager, hvad_to_dict from functions.signal_handlers import post_save_handler, pre_save_handler from functions.files import gen_path from hvad.models import TranslatableModel, TranslatedFields from service.models import Service from events.common import MEMBERS, VISITORS, PRICE, PRICE_EUR from events.models import TargetAudience # check if table exist and create flags if true #flags = [item.url for item in Service.objects.all()] if db_table_exists('service_service') else [] flags = ['catalog', 'translator', 'participation', 'remote', 'tickets', 'visit', 'buildstand'] CURRENCY = settings.CURRENCY class Conference(TranslatableModel, EventMixin, ExpoMixin): """ Create Conference model Uses hvad.TranslatableModel which is child of django.db.models class """ catalog = '/conference/' catalog_name = _(u'Конференции:') # type of event event_type = 'conf' #set manager of this model objects = ExpoManager() enable = ClientManager() url = models.SlugField(unique=True, max_length=255) bad_url = models.BooleanField(verbose_name=_(u'Подозрение на неправильный урл'), default=False) old_url = models.SlugField(unique=True, max_length=255) data_begin = models.DateField(verbose_name=_(u'Дата начала'), db_index=True) data_end = models.DateField(verbose_name=_(u'Дата окончания')) services = BitField(flags=flags, blank=True, null=True) #relations country = models.ForeignKey('country.Country', verbose_name=_(u'Страна'), on_delete=models.PROTECT, related_name='conference_country') city = models.ForeignKey('city.City', verbose_name=_(u'Город'), on_delete=models.PROTECT, related_name='conference_city') place = models.ForeignKey('place_conference.PlaceConference', verbose_name=_(u'Место проведения'), blank=True, null=True, on_delete=models.PROTECT, related_name='conference_place') place_alt = models.CharField(blank=True, null=True, max_length=255) # alternative for object place theme = models.ManyToManyField('theme.Theme', verbose_name=_(u'Тематики'), related_name='conference_themes') tag = models.ManyToManyField('theme.Tag', verbose_name=_(u'Теги'), blank=True, null=True, related_name='conference_tags') organiser = models.ManyToManyField('organiser.Organiser', verbose_name=_(u'Организатор'), blank=True, null=True, related_name='conference_organisers') org = models.CharField(max_length=255, blank=True, null=True) company = models.ManyToManyField('company.Company', verbose_name=_(u'Компании'), blank=True, null=True, related_name='conference_companies') users = models.ManyToManyField('accounts.User', verbose_name=_(u'Посетители выставки'), blank=True, null=True, related_name='conference_users') speakers = models.ManyToManyField('conference.Speaker', blank=True, null=True) photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True, on_delete=models.SET_NULL) logo = models.ImageField(verbose_name='Logo', upload_to='conference/logo/', blank=True) rating = models.IntegerField(default=0, db_index=True) # добавить индекс в базе quality_label = BitField(flags=['ufi', 'rsva', 'exporating']) periodic_once = models.CharField(verbose_name=_(u'Проводится в n-й раз'), help_text=_(u'10'), max_length=10, blank=True, null=True) periodic = models.FloatField(verbose_name=_(u'Переодичность'), blank=True, null=True) audience = models.ManyToManyField(TargetAudience, null=True) web_page = models.CharField(verbose_name=_(u'Вебсайт'), max_length=255, blank=True) link = models.CharField(verbose_name=_(u'Линк на регистрацию'), max_length=255, blank=True) programm_link = models.URLField(verbose_name=_(u'Программа конференции'), max_length=255, blank=True) discount = models.PositiveIntegerField(verbose_name=_(u'Скидка'), blank=True, null=True) partner = models.NullBooleanField(_(u"Партнер"), blank=True, null=True, default=False) # currency = EnumField(values=CURRENCY, default='USD') tax = models.BooleanField(verbose_name=_(u'Налог'), default=1) min_price = models.PositiveIntegerField(verbose_name=_(u'Минимальная цена'), blank=True, null=True) max_price = models.PositiveIntegerField(verbose_name=_(u'Максимальная цена'), blank=True, null=True) #administrator can cancel conference expohit = models.BooleanField(verbose_name='Expohit', default=0) canceled_by_administrator = models.BooleanField(default=0) canceled = models.BooleanField(default=0) moved = models.BooleanField(default=0) #can publish not immediately is_published = models.BooleanField(default=0, db_index=True) files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id') # statistic foundation_year = models.PositiveIntegerField(verbose_name=_(u'Год основания'), blank=True, null=True) visitors = models.PositiveIntegerField(verbose_name=_(u'Посетитеил'), blank=True, null=True) members = models.PositiveIntegerField(verbose_name=_(u'Участники'), blank=True, null=True) # fc = forecast - прогноз members_fc = models.PositiveIntegerField(verbose_name=_(u'Ожидаемое количество участников'), blank=True, null=True) #translated fields translations = TranslatedFields( name=models.CharField(verbose_name=_(u'Название'), max_length=255), main_title=models.TextField(verbose_name=_(u'Краткое описание'), blank=True), description=models.TextField(verbose_name=_(u'Описание'), blank=True), main_themes=models.TextField(verbose_name=_(u'Основные темы'), blank=True), time=models.TextField(verbose_name=_(u'Время работы'), blank=True), discount_description=models.TextField(verbose_name=_(u'Описание скидки'), blank=True), #-----meta data title=models.CharField(max_length=250), descriptions=models.CharField(max_length=250), keywords=models.CharField(max_length=250), ) paid_new = models.ForeignKey('expobanner.Paid', blank=True, null=True, on_delete=models.SET_NULL) top = models.ForeignKey('expobanner.Top', blank=True, null=True, on_delete=models.SET_NULL) main = models.ForeignKey('expobanner.MainPage', blank=True, null=True, on_delete=models.SET_NULL) #fields saves information about creating and changing model created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) main_page = models.PositiveIntegerField(default=0, db_index=True) views = models.PositiveIntegerField(default=0) # fields for filter easy members_choice = models.PositiveSmallIntegerField( _(u'Участники'), choices=MEMBERS, blank=True, null=True, db_index=True) visitors_choice = models.PositiveSmallIntegerField( _(u'Посетители'), choices=VISITORS, blank=True, null=True, db_index=True) price_choice = models.PositiveSmallIntegerField( _(u'Минимальная цена'), choices=PRICE, blank=True, null=True, db_index=True) price_rub = models.PositiveIntegerField(verbose_name=_(u'Рублевая цена'), blank=True, null=True) price_choice_eur = models.PositiveSmallIntegerField( _(u'Минимальная цена'), choices=PRICE_EUR, blank=True, null=True, db_index=True) price_eur = models.PositiveIntegerField(verbose_name=_(u'Цена в евро'), blank=True, null=True) comments = generic.GenericRelation('comments.Comment') def __unicode__(self): return self.lazy_translation_getter('name', unicode(self.pk)) def get_audience(self): return self.audience.all() def get_news_url(self): return reverse_lazy('news_conference', kwargs={'slug': self.url}) def get_catalog_url(self): return '/conference/' def get_calendar_url(self): return reverse_lazy('conference_add_calendar', args=[self.id]) def get_visit_url(self): return reverse_lazy( 'events:event_visit', args=['conference', self.id] ) def tags(self): return self.tag.language().all() def get_index_text(self): translation.activate('ru') translations = self.translations.all() names = ' '.join([tr.name for tr in translations]) titles = ' '.join([tr.main_title for tr in translations]) themes = ' '.join([' '.join(theme.get_all_names()) for theme in self.theme.all()]) tags = ' '.join([' '.join(tag.get_all_names()) for tag in self.tag.all()]) return names + ' ' + titles + ' ' + themes + ' ' + tags def upload_photo_url(self): return reverse_lazy('conference_upload_photo', args=[self.id]) def clicks(self): return self.paid_new.tickets.clicks() + self.paid_new.official.clicks() def get_paid_change_url(self): return reverse_lazy('confbanner-update_paid', kwargs={'pk': self.paid_new_id}) def get_objectstat_views(self): return sum(self.objectstats_set.all().values_list('value', flat=True)) class Speaker(models.Model): class Meta: verbose_name = _(u'Спикер') verbose_name_plural = _(u'Спикеры') fullname = models.CharField(_(u'Имя и фамилия'), max_length=255) company = models.CharField(_(u'Компания'), max_length=255, null=True, blank=True) position = models.CharField(_(u'Должность'), max_length=255, null=True, blank=True) photo = models.ImageField(_(u'Фото'), upload_to=gen_path) def __unicode__(self): return unicode(self.fullname) class Statistic(TranslatableModel): conference = models.ForeignKey(Conference, related_name='statistic') year = models.PositiveIntegerField(verbose_name=_(u'Год')) members = models.PositiveIntegerField(verbose_name=_(u'Посетители'), blank=True, null=True) visitors = models.PositiveIntegerField(verbose_name=_(u'Участники'), blank=True, null=True) area = models.PositiveIntegerField(verbose_name=_(u'Площадь'), blank=True, null=True) countries_number = models.PositiveIntegerField(verbose_name=_(u'Количество стран'), blank=True, null=True) translations = TranslatedFields( countries = models.TextField(blank=True) ) def to_dict(self): return hvad_to_dict(self) class TimeTable(TranslatableModel): """ TimeTable for business program """ conference = models.ForeignKey(Conference, related_name='business_program') begin = models.DateTimeField(verbose_name=_(u'Начало')) end = models.DateTimeField(verbose_name=_(u'Конец')) timetable_organiser = models.ForeignKey('organiser.Organiser', null=True, blank=True, related_name='conf_timetable') # created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) #translated fields translations = TranslatedFields( name = models.CharField(verbose_name=_(u'Название программы'), max_length=255, blank=True), programe = models.TextField(verbose_name=_(u'Программа')), speaker = models.CharField(verbose_name=_(u'Спикеры'), max_length=255, blank=True), place = models.CharField(verbose_name=_(u'Место проведения'), max_length=255, blank=True) ) def to_dict(self): return hvad_to_dict(self) pre_save.connect(pre_save_handler, sender=Conference) post_save.connect(post_save_handler, sender=Conference) post_save.connect(post_save_handler, sender=TimeTable) post_save.connect(post_save_handler, sender=Statistic)