remotes/origin/1203
Nazar Kotjuk 10 years ago
parent ae052d11ea
commit 898b0b7a9a
  1. 2
      exposition/management/commands/exposition_en.py
  2. 4
      functions/admin_views.py
  3. 70
      import_xls/admin.py
  4. 10
      import_xls/admin_urls.py
  5. 501
      import_xls/excel_settings.py
  6. 22
      import_xls/export_forms.py
  7. 173
      import_xls/import_forms.py
  8. 57
      place_conference/admin.py
  9. 4
      place_conference/admin_urls.py
  10. 53
      place_conference/forms.py
  11. 47
      place_conference/models.py
  12. 26
      place_exposition/forms.py
  13. 15
      place_exposition/models.py
  14. 2
      place_exposition/views.py
  15. 6
      templates/admin/includes/admin_nav.html
  16. 340
      templates/admin/place_conference/place_conference.html
  17. 2
      templates/admin/place_conference/place_conference_list.html
  18. 86
      templates/client/includes/place/place_info.html
  19. 408
      templates/client/includes/place/place_object.html
  20. 80
      templates/client/includes/place/place_services.html

@ -4,7 +4,7 @@ from city.models import City
from country.models import Country
from place_exposition.models import PlaceExposition
import xlrd, xlwt
from import_xls.excel_settings import import_settings, place_exp_sett
from import_xls.excel_settings import place_exp_sett
from django.conf import settings

@ -128,9 +128,9 @@ class AdminListView(FormView):
def get_context_data(self, **kwargs):
context = super(AdminListView, self).get_context_data(**kwargs)
if issubclass(self.model, TranslatableModel):
qs = self.model.objects.language('all').all().order_by('name')
qs = self.model.objects.language().all().order_by('name')
else:
qs = self.model.objects.all().order_by('name')
qs = self.model.objects.all().order_by('-modified')
result = paginate_results(qs, page=self.request.GET.get('page'))
context['object_list'] = result
return context

@ -1,22 +1,17 @@
# -*- coding: utf-8 -*-
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
from django.db.models.loading import get_model
#
import xlwt
import xlrd
#
from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, ImportOrganiserForm,\
ImportPlaceConferenceForm, ImportPlaceExpositionForm
from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
ExportCityForm
from django.views.generic import FormView, ListView, DeleteView
from django.conf import settings
from django.contrib import messages
from django.shortcuts import get_object_or_404
from import_xls.models import Log
from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, \
ImportPlaceConferenceForm, ImportPlaceExpositionForm
from export_forms import ExportEventForm, ExportThemeForm, ExportTagForm,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
ExportCityForm
def xls_to_response(xls, fname):
response = HttpResponse(mimetype="application/ms-excel")
@ -41,7 +36,6 @@ class ImportView(FormView):
return render_to_response(self.template_name, context)
class ExportView(FormView):
"""
abstract class
@ -57,85 +51,93 @@ class ExportView(FormView):
return HttpResponseRedirect(self.success_url)
return xls_to_response(workbook, f_name)
class ExportOrganiser(ExportView):
form_class = ExportOrganiserForm
success_url = '/admin/export-organiser'
class ExportTheme(ExportView):
form_class = ExportThemeForm
success_url = '/admin/export-theme'
class ExportTag(ExportView):
form_class = ExportTagForm
success_url = '/admin/export-tag'
class ExportUser(ExportView):
form_class = ExportUserForm
success_url = '/admin/export-user'
class ExportCompany(ExportView):
form_class = ExportCompanyForm
success_url = '/admin/export-company'
class ExportPlaceConference(ExportView):
form_class = ExportPlaceConferenceForm
success_url = '/admin/export-place_conference'
class ExportPlaceExposition(ExportView):
form_class = ExportPlaceExpositionForm
success_url = '/admin/export-place_exposition'
class ExportBlog(ExportView):
form_class = ExportBlogForm
success_url = '/admin/export-blog/'
class ExportBlog(ExportView):
form_class = ExportBlogForm
success_url = '/admin/export-blog/'
class ExportCity(ExportView):
form_class = ExportCityForm
success_url = '/admin/export-city/'
from import_xls.models import Log
class ImportEvent(FormView):
form_class = ImportEventForm
success_url = '/admin/import-event/'
template_name = 'admin/import templates/import_event.html'
def form_valid(self, form):
errors = form.save_file_debug()
return HttpResponseRedirect('/admin/import/log/')
#messages.success(self.request, 'Success')
#context = self.get_context_data()
#context['import_errors'] = errors
#context['form'] = form
#return render_to_response(self.template_name, context)
class ImportPlaceExposition(FormView):
form_class = ImportPlaceExpositionForm
success_url = '/admin/import-place_exposition/'
template_name = 'admin/import templates/import.html'
def form_valid(self, form):
errors = form.save_file_debug()
return HttpResponseRedirect(self.success_url)
class ImportPlaceConference(ImportView):
form_class = ImportPlaceConferenceForm
success_url = '/admin/import-place_conference'
def form_valid(self, form):
errors = form.save_file_debug()
return HttpResponseRedirect(self.success_url)
class ImportTheme(ImportView):
form_class = ImportThemeForm
success_url = '/admin/import-theme'
class ImportTag(ImportView):
form_class = ImportTagForm
success_url = '/admin/import-tag'
class ImportOrganiser(ImportView):
form_class = ImportOrganiserForm
success_url = '/admin/import-organiser'
class ImportPlaceExposition(ImportView):
form_class = ImportPlaceExpositionForm
success_url = '/admin/import-place_exposition'
class ImportPlaceConference(ImportView):
form_class = ImportPlaceConferenceForm
success_url = '/admin/import-place_conference'
class ExportEvent(ExportView):
form_class = ExportEventForm
@ -148,6 +150,7 @@ class LogList(ListView):
paginate_by = settings.ADMIN_PAGINATION
template_name = 'admin/import templates/log.html'
class LogDelete(DeleteView):
model = Log
success_url = '/admin/import/log/'
@ -163,11 +166,12 @@ def log_file(request, log_id):
response['X-Accel-Redirect'] = log.log.url
return response
def work_file(request, log_id):
log = get_object_or_404(Log, id=log_id)
response = HttpResponse()
response['content-type'] = 'application/x-executable'
filename = 'import_%s_file.xls'%str(log.id)
filename = 'import_%s_file.xls' % str(log.id)
response['content-disposition'] = 'attachment;filename=%s'%filename
response['X-Accel-Redirect'] = log.work_file.url
return response

@ -1,25 +1,21 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference
from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\
ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList
from import_xls.admin import LogDelete
from admin import ImportTheme, ImportEvent, ImportTag, ImportPlaceExposition, ImportPlaceConference
from admin import ExportTheme, ExportEvent, ExportTag, ExportPlaceExposition,\
ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList
urlpatterns = patterns('',
url(r'^import-event/$', ImportEvent.as_view()),
url(r'^import-theme/$', ImportTheme.as_view()),
url(r'^import-tag/$', ImportTag.as_view()),
url(r'^import-organiser/$', ImportOrganiser.as_view()),
url(r'^import-place_exposition/$', ImportPlaceExposition.as_view()),
url(r'^import-place_conference/$', ImportPlaceConference.as_view()),
#
url(r'^export-event/$', ExportEvent.as_view()),
url(r'^export-theme/$', ExportTheme.as_view()),
url(r'^export-tag/$', ExportTag.as_view()),
url(r'^export-organiser/$', ExportOrganiser.as_view()),
url(r'^export-place_exposition/$', ExportPlaceExposition.as_view()),
url(r'^export-place_conference/$', ExportPlaceConference.as_view()),
url(r'^export-user/$', ExportUser.as_view()),

@ -1,12 +1,22 @@
# -*- coding: utf-8 -*-
import urllib2
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.validators import validate_email, URLValidator
from file.models import FileModel
from functions.files import get_alternative_filename
from place_exposition.models import EXPOSITION_TYPE
from place_exposition.models import Hall
# bad practice of importing, but to many functions must be imported
from .utils import *
def get_bool(value):
if value:
return 1
return ''
def get_int(value):
if not value:
return ''
@ -30,12 +40,14 @@ def get_tag(value):
tag_names = [item['name'] for item in value.language('ru').all().values('name')]
return ','.join(tag_names)
def get_place_type(value):
for t in EXPOSITION_TYPE:
if value == t[0]:
return t[1]
return t[0][1]
def get_periodic(value):
if value:
value = float(value)
@ -45,6 +57,7 @@ def get_periodic(value):
return periodic.get(value, '')
return ''
def get_quality(value, field):
flags = {u'UFI': 'ufi', u'РСВЯ': 'rsva', u'EXPORATING': 'exporating'}
v = flags.get(field)
@ -56,45 +69,6 @@ def get_quality(value, field):
return ''
place_settings=[
{'name': 'id', 'verbose_name': u'id', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'URL', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'type', 'verbose_name': u'Тип', 'type': get_place_type},##########
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'address', 'verbose_name': u'Адресс', 'type': unicode},
{'name': 'phone', 'verbose_name': u'Тел.', 'type': get_int},
{'name': 'fax', 'verbose_name': u'Факс', 'type': get_int},
{'name': 'web_page', 'verbose_name': u'Веб-сайт', 'type': unicode},
{'name': 'email', 'verbose_name': u'Email', 'type': unicode},
{'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode},
{'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'event_in_year', 'verbose_name': u'Количество мероприятий в год', 'type': get_int},
{'name': 'total_area', 'verbose_name': u'Общая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'closed_area', 'verbose_name': u'Закрытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'open_area', 'verbose_name': u'Открытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'total_pavilions', 'verbose_name': u'Количество павильонов', 'type': get_int},
{'name': 'total_halls', 'verbose_name': u'Конференц-залы', 'type': get_int},
{'name': 'bank', 'verbose_name': u'Банк/Банкоматы/Обмен валюты', 'type': get_bool},
{'name': 'children_room', 'verbose_name': u'Детская комната', 'type': get_bool},
{'name': 'disabled_service', 'verbose_name': u'Сервис для людей с ограниченными физическими возможностями', 'type': get_bool},
{'name': 'conference_centre', 'verbose_name': u'Конгресс-центр', 'type': get_bool},
{'name': 'business_centre', 'verbose_name': u'Бизнес-центр', 'type': get_bool},
{'name': 'online_registration', 'verbose_name': u'On-line регистрация', 'type': get_bool},
{'name': 'wifi', 'verbose_name': u'Wi-Fi', 'type': get_bool},
{'name': 'cafe', 'verbose_name': u'Кафе и рестораны', 'type': get_bool},
{'name': 'terminals', 'verbose_name': u'Информационные терминалы', 'type': get_bool},
{'name': 'parking', 'verbose_name': u'Парковка', 'type': get_bool},
{'name': 'press_centre', 'verbose_name': u'Пресс-центр', 'type': get_bool},
{'name': 'mobile_application', 'verbose_name': u'Мобильное приложение', 'type': get_bool},
]
def to_theme_type(st):
if not st:
return 15
@ -105,37 +79,15 @@ def to_theme_type(st):
return flag
def to_currency(value):
if value=='USD':
return value
if value=='EUR':
return value
print(value)
return 'USD'
def to_logo(url):
return None
def to_photo(url):
return None
def to_map(url):
return None
from django.core.validators import validate_email, URLValidator
def to_url(url):
validate = URLValidator()
try:
validate(url)
except:
return ''
return url
def to_email(email):
try:
validate_email(email)
@ -143,12 +95,6 @@ def to_email(email):
return ''
return email
from file.models import FileModel
import urllib2
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from functions.files import get_alternative_filename
def save_file(obj, value, purpose):
if not obj.id:
@ -178,42 +124,13 @@ def save_file(obj, value, purpose):
file.save()
from file.models import Photo
def save_photo(obj, value):
if not obj.id:
return None
urls = value.split(';')
for url in urls:
file_name = url.split('/')[-1]
alt_name = get_alternative_filename(settings.MEDIA_ROOT+'imgs/', file_name)
download_to = settings.MEDIA_ROOT+'photos/'+alt_name
try:
response = urllib2.urlopen(url, timeout=3)
except:
continue
with open(download_to,'wb') as f:
f.write(response.read())
f.close()
file_name ='photos/'+alt_name
content_type = ContentType.objects.get_for_model(obj)
photo = Photo(file_path=file_name, file_type='JPG',
content_type=content_type, object_id=obj.id)
photo.save()
from place_exposition.models import EXPOSITION_TYPE
def to_type(value):
for t in EXPOSITION_TYPE:
if value == t[1]:
return t[0]
return 'Exposition complex'
def to_phone(value):
if value:
if isinstance(value, float) or isinstance(value, int):
@ -227,9 +144,6 @@ def to_phone(value):
return value
from place_exposition.models import Hall
def save_halls(obj, value):
halls = value.split(';')
res = []
@ -266,51 +180,11 @@ def save_halls(obj, value):
print('---------------------------------')
place_exp_sett = {
u'ID':{u'field': u'id', u'func': to_int},
u'Название ВЦ':{u'field': u'name', u'func': unicode},
u'Тип':{u'field': u'type', u'func': to_type},
u'Краткое описание':{u'field': u'main_title', u'func': unicode},
u'Страна':{u'field': u'country', u'func': to_country},
u'Город':{u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Описание':{u'field': u'description', u'func': unicode},
u'Адрес':{u'field': u'adress', u'func': unicode},
u'Тел.':{u'field': u'phone', u'func': to_phone},
u'Факс':{u'field': u'fax', u'func': to_phone},
u'Фото':{u'field': u'photo', u'func': save_photo, u'method': True},
u'Лого':{u'field': u'logo', u'func': save_logo, u'method': True},
u'Веб-сайт':{u'field': u'web_page', u'func': unicode},
u'Email':{u'field': u'email', u'func': unicode},
u'Карта проезда':{u'field': u'map', u'func': save_file, u'method': True, u'purpose': 'map'},
u'Виртуальный тур':{u'field': u'virtual_tour', u'func': to_url},
u'Год основания':{u'field': u'foundation_year', u'func': to_int},
u'Валюта':{u'field': u'currency', u'func': to_currency},
u'Количество мероприятий в год':{u'field': u'event_in_year', u'func': to_int},
u'Общая выставочная площадь, кв. м.':{u'field': u'total_area', u'func': to_int},
u'Закрытая выставочная площадь, кв. м.':{u'field': u'closed_area', u'func': to_int},
u'Открытая выставочная площадь, кв. м.':{u'field': u'open_area', u'func': to_int},
u'Количество павильонов':{u'field': u'total_pavilions', u'func': to_int},
u'Площадь павильона':{u'field': u'halls', u'func': save_halls, u'method': True},
u'Конференц-залы':{u'field': u'total_halls', u'func': to_int},
u'Схема территории':{u'field': u'scheme', u'func': save_file, u'method': True, u'purpose': 'scheme teritory'},#сделать
u'Банк/Банкоматы/Обмен валюты':{u'field': u'bank', u'func': bool},
u'Детская комната':{u'field': u'children_room', u'func': bool},
u'Сервис для людей с ограниченными физическими возможностями':{u'field': u'disabled_service', u'func': bool},
u'Конгресс-центр':{u'field': u'conference_centre', u'func': bool},
u'Бизнес-центр':{u'field': u'business_centre', u'func': bool},
u'On-line регистрация':{u'field': u'online_registration', u'func': bool},
u'Wi-Fi':{u'field': u'wifi', u'func': bool},
u'Кафе и рестораны':{u'field': u'cafe', u'func': bool},
u'Информационные терминалы':{u'field': u'terminals', u'func': bool},
u'Парковка':{u'field': u'parking', u'func': bool},
u'Пресс-центр':{u'field': u'press_centre', u'func': bool},
u'Мобильное приложение':{u'field': u'mobile_application', u'func': bool},
}
def get_date(value):
try:
return value.strftime('%d.%m.%Y')
except AttributeError:
return ''
article_sett = {
@ -321,66 +195,7 @@ article_sett = {
u'Создана':{u'field': u'created', u'func': to_datetime}
}
def get_date(value):
try:
return value.strftime('%d.%m.%Y')
except AttributeError:
return ''
event_export_sett = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': get_date},
{'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': get_date},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place},
{'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000},
{'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000},
{'name': 'description', 'verbose_name': u'Описание события', 'type': unicode},
{'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int},
{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic},
{'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience},
{'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode},
{'name': 'products', 'verbose_name': u'Экспонируемые продукты', 'type': unicode},
{'name': 'time', 'verbose_name': u'Время работы', 'type': unicode},
{'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode},
{'name': 'currency', 'verbose_name': u'Валюта', 'type': unicode},
{'name': 'price_day', 'verbose_name': u'Стоимость билета 1 день', 'type': unicode},
{'name': 'price_all', 'verbose_name': u'Стоимость билета все дни', 'type': unicode},
{'name': 'pre_condition', 'verbose_name': u'Условия предварительной регистрации', 'type': unicode},
{'name': 'price_day_bar', 'verbose_name': u'Стоимость на стойке 1 день', 'type': unicode},
{'name': 'price_all_bar', 'verbose_name': u'Стоимость на стойке все дни', 'type': unicode},
{'name': 'stand_condition', 'verbose_name': u'Условия регистрации на стойке', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Примечание по посещению', 'type': unicode},
{'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int},
{'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'visitors', 'verbose_name': u'Посетители', 'type': get_int},
{'name': 'members', 'verbose_name': u'Участники', 'type': get_int},
#{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode}, !!! delete from import
{'name': 'area', 'verbose_name': u'Площадь', 'type': get_int},
{'name': 'min_closed_area', 'verbose_name': u'Min_Raw кв.м.', 'type': get_int},
{'name': 'max_closed_area', 'verbose_name': u'Max_Raw кв.м.', 'type': get_int},
{'name': 'min_closed_equipped_area', 'verbose_name': u'Min_Pack кв.м.', 'type': get_int},
{'name': 'max_closed_equipped_area', 'verbose_name': u'Max_Pack кв.м.', 'type': get_int},
{'name': 'max_open_area', 'verbose_name': u'Открытая площадь', 'type': get_int},
{'name': 'min_stand_size', 'verbose_name': u'Мин. Площадь кв.м.', 'type': get_int},
{'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int},
{'name': 'participation_note', 'verbose_name': u'Примечание по участии', 'type': unicode},
{'name': 'application_deadline', 'verbose_name': u'Крайний срок подачи заявки', 'type': get_date},
{'name': 'quality_label', 'verbose_name': u'UFI', 'type': get_quality}, #????
{'name': 'quality_label', 'verbose_name': u'РСВЯ', 'type': get_quality},#???
{'name': 'quality_label', 'verbose_name': u'EXPORATING', 'type': get_quality}, #???
{'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool},
{'name': 'expohit', 'verbose_name': u'ExpoHIT', 'type': get_bool},
{'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool},
]
# default export settings
field_settings = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
@ -412,8 +227,6 @@ field_settings = [
{'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int},
{'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'visit_note', 'verbose_name': u'Посетители', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Участники', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode},
@ -424,7 +237,6 @@ field_settings = [
{'name': 'visit_note', 'verbose_name': u'Max_Pack кв.м.', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Открытая площадь', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Мин. Площадь кв.м.', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Примечание по участии', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Крайний срок подачи заявки', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'UFI', 'type': unicode},
@ -432,21 +244,13 @@ field_settings = [
{'name': 'visit_note', 'verbose_name': u'EXPORATING', 'type': unicode},
{'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool},
{'name': 'visit_note', 'verbose_name': u'ExpoHIT', 'type': unicode},
{'name': 'address', 'verbose_name': u'Адрес', 'type': unicode},
{'name': 'email', 'verbose_name': u'Email', 'type': unicode},
{'name': 'phone', 'verbose_name': u'Телефон', 'type': get_int},
{'name': 'foundation', 'verbose_name': u'Год основания', 'type': get_int},
#{'name': 'events_number', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'staff_number', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'specialization', 'verbose_name': u'Год основания', 'type': unicode},
{'name': 'max_price', 'verbose_name': u'Максимальная цена', 'type': get_int},
{'name': 'min_price', 'verbose_name': u'Минимальная цена', 'type': get_int},
{'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int},
@ -459,68 +263,221 @@ field_settings = [
{'name': 'min_area', 'verbose_name': u'Минимальная площадь', 'type': get_int},
{'name': 'max_area', 'verbose_name': u'Максимальная площадь', 'type': get_int},
{'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool},
]
# ----------------------EVENT SETTINGS -------------------------
event_sett = {
u'ID':{u'field': u'id', u'func': to_int},
u'Url':{u'field': u'url', u'func': unicode},
u'Название':{u'field': u'name', u'func': unicode},
u'Краткое описание':{u'field': u'main_title', u'func': unicode},
u'Дата начала:(YYYY-MM-DD)':{u'field': u'data_begin', u'func': to_date},
u'Дата окончания:(YYYY-MM-DD)':{u'field': u'data_end', u'func': to_date},
u'Страна':{u'field': u'country', u'func': to_country},
u'Город':{u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Место проведения':{u'field': u'place', u'func': to_place},
u'ID Тематики':{u'field': u'theme', u'func': to_theme, u'method': True},###
u'Теги':{u'field': u'tag', u'func': to_tag, u'method': True},
u'Организатор №1':{u'field': u'org', u'func': unicode},####
u'ID': {u'field': u'id', u'func': to_int},
u'Url': {u'field': u'url', u'func': unicode},
u'Название': {u'field': u'name', u'func': unicode},
u'Краткое описание': {u'field': u'main_title', u'func': unicode},
u'Дата начала:(YYYY-MM-DD)': {u'field': u'data_begin', u'func': to_date},
u'Дата окончания:(YYYY-MM-DD)': {u'field': u'data_end', u'func': to_date},
u'Страна': {u'field': u'country', u'func': to_country},
u'Город': {u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Место проведения': {u'field': u'place', u'func': to_place},
u'ID Тематики': {u'field': u'theme', u'func': to_theme, u'method': True},###
u'Теги': {u'field': u'tag', u'func': to_tag, u'method': True},
u'Организатор №1': {u'field': u'org', u'func': unicode},####
#u'Организатор №2':{u'field': u'organiser', u'func': to_tag},####
u'Описание события':{u'field': u'description', u'func': unicode},
u'Основные темы':{u'field': u'main_themes', u'func': unicode},
u'Условия и скидка':{u'field': u'discount_description', u'func': unicode},
u'Периодичность':{u'field': u'periodic', u'func': to_periodic},###
u'Аудитория':{u'field': u'audience', u'func': to_audience},
u'Официальный веб-сайт':{u'field': u'web_page', u'func': to_url},
u'Линк на регистрацию':{u'field': u'link', u'func': to_url},
u'Экспонируемые продукты':{u'field': u'products', u'func': unicode},
u'Время работы':{u'field': u'time', u'func': unicode},
u'Описание события': {u'field': u'description', u'func': unicode},
u'Основные темы': {u'field': u'main_themes', u'func': unicode},
u'Условия и скидка': {u'field': u'discount_description', u'func': unicode},
u'Периодичность': {u'field': u'periodic', u'func': to_periodic},###
u'Аудитория': {u'field': u'audience', u'func': to_audience},
u'Официальный веб-сайт': {u'field': u'web_page', u'func': to_url},
u'Линк на регистрацию': {u'field': u'link', u'func': to_url},
u'Экспонируемые продукты': {u'field': u'products', u'func': unicode},
u'Время работы': {u'field': u'time', u'func': unicode},
u'Логотип':{u'field': u'logo', u'func': save_logo, u'method': True},
u'Валюта':{u'field': u'currency', u'func': unicode},
u'Стоимость билета 1 день':{u'field': u'price_day', u'func': unicode},
u'Стоимость билета все дни':{u'field': u'price_all', u'func': unicode},
u'Условия предварительной регистрации':{u'field': u'pre_condition', u'func': unicode},
u'Стоимость на стойке 1 день':{u'field': u'price_day_bar', u'func': unicode},
u'Стоимость на стойке все дни':{u'field': u'price_all_bar', u'func': unicode},
u'Условия регистрации на стойке':{u'field': u'stand_condition', u'func': unicode},
u'Примечание по посещению':{u'field': u'visit_note', u'func': unicode},
u'Каталог':{u'field': u'price_catalog', u'func': to_int},
u'Налог включен':{u'field': u'tax', u'func': bool},
u'Год основания':{u'field': u'foundation_year', u'func': to_int},
#???u'Данные за год':{u'field': u'periodic', u'func': to_int},
u'Посетители':{u'field': u'visitors', u'func': to_int},
u'Участники':{u'field': u'members', u'func': to_int},
u'Страны':{u'field': u'stat_countries', u'func': unicode},
u'Площадь':{u'field': u'area', u'func': to_int},
u'Мин стоимость':{u'field': u'min_price', u'func': to_int},
u'Макс стоимость':{u'field': u'max_price', u'func': to_int},
u'Min_Raw кв.м.':{u'field': u'min_closed_area', u'func': to_int},
u'Max_Raw кв.м.':{u'field': u'max_closed_area', u'func': to_int},
u'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int},
u'Max_Pack кв.м.':{u'field': u'max_closed_equipped_area', u'func': to_int},
u'Открытая площадь':{u'field': u'max_open_area', u'func': to_int},
u'Мин. Площадь кв.м.':{u'field': u'min_stand_size', u'func': to_int},
u'Регистрационный взнос':{u'field': u'registration_payment', u'func': to_int},
u'Примечание по участии':{u'field': u'participation_note', u'func': unicode},
u'Крайний срок подачи заявки':{u'field': u'application_deadline', u'func': to_date},
u'UFI':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'ufi'},
u'РСВЯ':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'rsva'},
u'EXPORATING':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'exporating'},
u'Отменена':{u'field': u'canceled', u'func': bool},
u'ExpoHIT':{u'field': u'expohit', u'func': bool},
u'Валюта': {u'field': u'currency', u'func': unicode},
u'Стоимость билета 1 день': {u'field': u'price_day', u'func': unicode},
u'Стоимость билета все дни': {u'field': u'price_all', u'func': unicode},
u'Условия предварительной регистрации': {u'field': u'pre_condition', u'func': unicode},
u'Стоимость на стойке 1 день': {u'field': u'price_day_bar', u'func': unicode},
u'Стоимость на стойке все дни': {u'field': u'price_all_bar', u'func': unicode},
u'Условия регистрации на стойке': {u'field': u'stand_condition', u'func': unicode},
u'Примечание по посещению': {u'field': u'visit_note', u'func': unicode},
u'Каталог': {u'field': u'price_catalog', u'func': to_int},
u'Налог включен': {u'field': u'tax', u'func': bool},
u'Год основания': {u'field': u'foundation_year', u'func': to_int},
u'Посетители': {u'field': u'visitors', u'func': to_int},
u'Участники': {u'field': u'members', u'func': to_int},
u'Страны': {u'field': u'stat_countries', u'func': unicode},
u'Площадь': {u'field': u'area', u'func': to_int},
u'Мин стоимость': {u'field': u'min_price', u'func': to_int},
u'Макс стоимость': {u'field': u'max_price', u'func': to_int},
u'Min_Raw кв.м.': {u'field': u'min_closed_area', u'func': to_int},
u'Max_Raw кв.м.': {u'field': u'max_closed_area', u'func': to_int},
u'Min_Pack кв.м.': {u'field': u'min_closed_equipped_area', u'func': to_int},
u'Max_Pack кв.м.': {u'field': u'max_closed_equipped_area', u'func': to_int},
u'Открытая площадь': {u'field': u'max_open_area', u'func': to_int},
u'Мин. Площадь кв.м.': {u'field': u'min_stand_size', u'func': to_int},
u'Регистрационный взнос': {u'field': u'registration_payment', u'func': to_int},
u'Примечание по участии': {u'field': u'participation_note', u'func': unicode},
u'Крайний срок подачи заявки': {u'field': u'application_deadline', u'func': to_date},
u'UFI': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'ufi'},
u'РСВЯ': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'rsva'},
u'EXPORATING': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'exporating'},
u'Отменена': {u'field': u'canceled', u'func': bool},
u'ExpoHIT': {u'field': u'expohit', u'func': bool},
}
event_export_sett = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': get_date},
{'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': get_date},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place},
{'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000},
{'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000},
{'name': 'description', 'verbose_name': u'Описание события', 'type': unicode},
{'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int},
{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic},
{'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience},
{'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode},
{'name': 'products', 'verbose_name': u'Экспонируемые продукты', 'type': unicode},
{'name': 'time', 'verbose_name': u'Время работы', 'type': unicode},
{'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode},
{'name': 'currency', 'verbose_name': u'Валюта', 'type': unicode},
{'name': 'price_day', 'verbose_name': u'Стоимость билета 1 день', 'type': unicode},
{'name': 'price_all', 'verbose_name': u'Стоимость билета все дни', 'type': unicode},
{'name': 'pre_condition', 'verbose_name': u'Условия предварительной регистрации', 'type': unicode},
{'name': 'price_day_bar', 'verbose_name': u'Стоимость на стойке 1 день', 'type': unicode},
{'name': 'price_all_bar', 'verbose_name': u'Стоимость на стойке все дни', 'type': unicode},
{'name': 'stand_condition', 'verbose_name': u'Условия регистрации на стойке', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Примечание по посещению', 'type': unicode},
{'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int},
{'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'visitors', 'verbose_name': u'Посетители', 'type': get_int},
{'name': 'members', 'verbose_name': u'Участники', 'type': get_int},
#{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode}, !!! delete from import
{'name': 'area', 'verbose_name': u'Площадь', 'type': get_int},
{'name': 'min_closed_area', 'verbose_name': u'Min_Raw кв.м.', 'type': get_int},
{'name': 'max_closed_area', 'verbose_name': u'Max_Raw кв.м.', 'type': get_int},
{'name': 'min_closed_equipped_area', 'verbose_name': u'Min_Pack кв.м.', 'type': get_int},
{'name': 'max_closed_equipped_area', 'verbose_name': u'Max_Pack кв.м.', 'type': get_int},
{'name': 'max_open_area', 'verbose_name': u'Открытая площадь', 'type': get_int},
{'name': 'min_stand_size', 'verbose_name': u'Мин. Площадь кв.м.', 'type': get_int},
{'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int},
{'name': 'participation_note', 'verbose_name': u'Примечание по участии', 'type': unicode},
{'name': 'application_deadline', 'verbose_name': u'Крайний срок подачи заявки', 'type': get_date},
{'name': 'quality_label', 'verbose_name': u'UFI', 'type': get_quality}, #????
{'name': 'quality_label', 'verbose_name': u'РСВЯ', 'type': get_quality},#???
{'name': 'quality_label', 'verbose_name': u'EXPORATING', 'type': get_quality}, #???
{'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool},
{'name': 'expohit', 'verbose_name': u'ExpoHIT', 'type': get_bool},
{'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool},
]
# -----------------------END EVENT SETTINGS ---------------------------------
# --------------PLACE EXPO SETTINGS-----------------------------
# import
place_exp_sett = {
u'ID': {u'field': u'id', u'func': to_int},
u'Название': {u'field': u'name', u'func': unicode},
u'Тип': {u'field': u'type', u'func': to_type},
u'Краткое описание': {u'field': u'main_title', u'func': unicode},
u'Страна': {u'field': u'country', u'func': to_country},
u'Город': {u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Описание': {u'field': u'description', u'func': unicode},
u'Адрес': {u'field': u'adress', u'func': unicode},
u'Тел.': {u'field': u'phone', u'func': to_phone},
u'Факс': {u'field': u'fax', u'func': to_phone},
u'Лого': {u'field': u'logo', u'func': save_logo, u'method': True},
u'Веб-сайт': {u'field': u'web_page', u'func': unicode},
u'Email': {u'field': u'email', u'func': unicode},
u'Карта проезда': {u'field': u'map', u'func': save_file, u'method': True, u'purpose': 'map'},
u'Виртуальный тур': {u'field': u'virtual_tour', u'func': to_url},
u'Год основания': {u'field': u'foundation_year', u'func': to_int},
u'Количество мероприятий в год': {u'field': u'event_in_year', u'func': to_int},
u'Общая выставочная площадь, кв. м.': {u'field': u'total_area', u'func': to_int},
u'Закрытая выставочная площадь, кв. м.': {u'field': u'closed_area', u'func': to_int},
u'Открытая выставочная площадь, кв. м.': {u'field': u'open_area', u'func': to_int},
u'Количество павильонов': {u'field': u'total_pavilions', u'func': to_int},
u'Площадь павильона': {u'field': u'halls', u'func': save_halls, u'method': True},
u'Конференц-залы': {u'field': u'total_halls', u'func': to_int},
u'Схема территории': {u'field': u'scheme', u'func': save_file, u'method': True, u'purpose': 'scheme teritory'},#сделать
u'Банк/Банкоматы/Обмен валюты': {u'field': u'bank', u'func': bool},
u'Детская комната': {u'field': u'children_room', u'func': bool},
u'Сервис для людей с ограниченными физическими возможностями': {u'field': u'disabled_service', u'func': bool},
u'Конгресс-центр': {u'field': u'conference_centre', u'func': bool},
u'Бизнес-центр': {u'field': u'business_centre', u'func': bool},
u'On-line регистрация': {u'field': u'online_registration', u'func': bool},
u'Wi-Fi': {u'field': u'wifi', u'func': bool},
u'Кафе и рестораны': {u'field': u'cafe', u'func': bool},
u'Информационные терминалы': {u'field': u'terminals', u'func': bool},
u'Парковка': {u'field': u'parking', u'func': bool},
u'Пресс-центр': {u'field': u'press_centre', u'func': bool},
u'Мобильное приложение': {u'field': u'mobile_application', u'func': bool},
# place_conf settings
u'Мультимедийное оборудование': {u'field': u'multimedia_equipment', u'func': bool},
u'Конференц-связь': {u'field': u'conference_call', u'func': bool},
u'Оборудование для синхронного перевода': {u'field': u'translate_equipment', u'func': bool},
u'Банкетный зал': {u'field': u'banquet_hall', u'func': bool},
u'Кейтеринг': {u'field': u'catering', u'func': bool},
u'Гостиница': {u'field': u'hotel', u'func': bool},
u'Выставочный зал': {u'field': u'exposition_hall', u'func': bool},
u'Площадь выст. зала': {u'field': u'exp_hall_area', u'func': to_int},
u'Общая вместимость': {u'field': u'total_capacity', u'func': to_int},
u'Количество залов': {u'field': u'amount_halls', u'func': bool},
}
# export
place_settings=[
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'type', 'verbose_name': u'Тип', 'type': get_place_type},##########
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'adress', 'verbose_name': u'Адресс', 'type': unicode},
{'name': 'phone', 'verbose_name': u'Тел.', 'type': get_int},
{'name': 'fax', 'verbose_name': u'Факс', 'type': get_int},
{'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode},
{'name': 'web_page', 'verbose_name': u'Веб-сайт', 'type': unicode},
{'name': 'email', 'verbose_name': u'Email', 'type': unicode},
{'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'event_in_year', 'verbose_name': u'Количество мероприятий в год', 'type': get_int},
{'name': 'total_area', 'verbose_name': u'Общая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'closed_area', 'verbose_name': u'Закрытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'open_area', 'verbose_name': u'Открытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'total_pavilions', 'verbose_name': u'Количество павильонов', 'type': get_int},
{'name': 'total_halls', 'verbose_name': u'Конференц-залы', 'type': get_int},
{'name': 'total_capacity', 'verbose_name': u'Общая вместимость', 'type': get_int},
{'name': 'exposition_hall', 'verbose_name': u'Выставочный зал', 'type': get_bool},
{'name': 'exp_hall_area', 'verbose_name': u'Площадь выст. зала', 'type': get_int},
{'name': 'amount_halls', 'verbose_name': u'Количество залов', 'type': get_int},
{'name': 'bank', 'verbose_name': u'Банк/Банкоматы/Обмен валюты', 'type': get_bool},
{'name': 'children_room', 'verbose_name': u'Детская комната', 'type': get_bool},
{'name': 'disabled_service', 'verbose_name': u'Сервис для людей с ограниченными физическими возможностями', 'type': get_bool},
{'name': 'conference_centre', 'verbose_name': u'Конгресс-центр', 'type': get_bool},
{'name': 'business_centre', 'verbose_name': u'Бизнес-центр', 'type': get_bool},
{'name': 'online_registration', 'verbose_name': u'On-line регистрация', 'type': get_bool},
{'name': 'wifi', 'verbose_name': u'Wi-Fi', 'type': get_bool},
{'name': 'cafe', 'verbose_name': u'Кафе и рестораны', 'type': get_bool},
{'name': 'terminals', 'verbose_name': u'Информационные терминалы', 'type': get_bool},
{'name': 'parking', 'verbose_name': u'Парковка', 'type': get_bool},
{'name': 'press_centre', 'verbose_name': u'Пресс-центр', 'type': get_bool},
{'name': 'mobile_application', 'verbose_name': u'Мобильное приложение', 'type': get_bool},
{'name': 'multimedia_equipment', 'verbose_name': u'Мультимедийное оборудование', 'type': get_bool},
{'name': 'conference_call', 'verbose_name': u'Конференц-связь', 'type': get_bool},
{'name': 'translate_equipment', 'verbose_name': u'Оборудование для синхронного перевода', 'type': get_bool},
{'name': 'banquet_hall', 'verbose_name': u'Банкетный зал', 'type': get_bool},
{'name': 'catering', 'verbose_name': u'Кейтеринг', 'type': get_bool},
{'name': 'hotel', 'verbose_name': u'Гостиница', 'type': get_bool},
]
# -----------------END PLACE EXPO SETTINGS------------------------------
# default import settings
import_settings={
'name': {'func': unicode},
'url': {'func': unicode},

@ -13,7 +13,7 @@ from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference
from django.db.models.loading import get_model
import xlwt
from excel_settings import import_settings, field_settings, event_export_sett
from excel_settings import field_settings, event_export_sett
languages = [code for code in settings.LANGUAGES]
@ -75,13 +75,6 @@ class ExportForm(forms.Form):
return self.workbook
class ExportOrganiserForm(ExportForm):
model = Organiser
def get_fname(self):
return 'organisers.xls'
class ExportUserForm(ExportForm):
model = User
@ -106,7 +99,9 @@ class ExportTagForm(ExportForm):
from excel_settings import place_settings
class ExportPlaceExpositionForm(ExportForm):
model = PlaceExposition
def export(self):
data = self.cleaned_data
objects = self.get_objects(data)
@ -130,21 +125,18 @@ class ExportPlaceExpositionForm(ExportForm):
self.worksheet.write(0, col, field.get('verbose_name', 'default'), self.style)
#self.worksheet.write(1, col, field.get('name'), self.style)
self.worksheet.col(col).width = field.get('width', 3333)
if field['name']=='tag':
self.worksheet.write(row+1, col, field.get('type')(value, object.theme))
else:
self.worksheet.write(row+1, col, field.get('type')(value))
self.worksheet.write(row+1, col, field.get('type')(value))
col += 1
return self.workbook
def get_fname(self):
return 'places.xls'
class ExportPlaceConferenceForm(ExportForm):
class ExportPlaceConferenceForm(ExportPlaceExpositionForm):
model = PlaceConference
def get_fname(self):
return 'places.xls'
class ExportCompanyForm(ExportForm):
model = Company

@ -1,18 +1,32 @@
# -*- coding: utf-8 -*-
import urllib
import json
import xlrd
from django.db import IntegrityError
from django import forms
from django.conf import settings
from django.db.models.loading import get_model
from theme.models import Theme, Tag
from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference
from country.models import Country
from organiser.models import Organiser
from django.db.models.loading import get_model
import xlrd, xlwt
from import_xls.models import Log
from excel_settings import import_settings
from functions.form_check import translit_with_separator
from excel_settings import place_exp_sett
from import_xls.excel_settings import event_sett
languages = [code for code in settings.LANGUAGES]
typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'country_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата окончания',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
def logcall(f, msg):
with open(f.file.name, 'a') as logfile:
logfile.write(msg.encode('utf8'))
class ImportForm(forms.Form):
"""
@ -82,19 +96,11 @@ class ImportForm(forms.Form):
object.save()
class ImportOrganiserForm(ImportForm):
model = Organiser
class ImportThemeForm(ImportForm):
model = Theme
from excel_settings import place_exp_sett
from django.db import IntegrityError
import urllib, json
def google_address(address):
if address:
address = address.encode('utf')
@ -112,13 +118,131 @@ def google_address(address):
return ''
return ''
from djutils.decorators import async
from djutils.queue.decorators import queue_command
# place
class ImportPlaceExpositionForm(ImportForm):
model = PlaceExposition
settings = place_exp_sett
def get_row_object(self, row):
if row[0] != '':
# in first column id
try:
obj = self.model.objects.language(self.lang).get(id=int(row[0]))
except ValueError:
obj = self.model()
obj.translate(self.lang)
except self.model.DoesNotExist:
obj = self.model(id= int(row[0]))
obj.translate(self.lang)
else:
# if id blank - its a new object
obj = self.model()
obj.translate(self.lang)
return obj
def save_file_debug(self):
data = self.cleaned_data
lang, self.lang = data['language'], data['language']
f = data['excel_file']
book = xlrd.open_workbook(file_contents=f.read())
sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
field_names = [name for name in row_list[0]]
model = self.model
labels = [label for label in row_list[0]]
errors = []
#log = Log.custom.create_log_name(f)
for row_number, row in enumerate(row_list):
if row_number == 0:
continue
#log_msg = u'[%s] %s: '%(str(row_number), row[2])
obj = self.get_row_object(row)
methods = []
# go through row cells
for col_number, cell in enumerate(row):
# get current label
label = labels[col_number]
setting = event_sett.get(label)
if setting is None:
# no label in settings
continue
if setting.get('method'):
# this cell contains data that must be written after creating object
if cell != "":
methods.append({'func': setting['func'], 'value': cell,
'purpose': setting.get('purpose'), 'field': label})
continue
field_name = setting['field']
func = setting.get('func')
if func is None:
# no function in settings
continue
extra_value = setting.get('extra_values')
if extra_value is not None:
# if setting has extra value then
# it is some field like city, tag
# that has relation and can be created
# in function we add language(need for relation fields)
# and extra value from object (like for city need country)
try:
extra = getattr(obj, extra_value)
except Exception:
continue
value = func(cell, 'ru', extra)
else:
value = func(cell)
#try:
setattr(obj, field_name, value)
#except ValueError:
# continue
if not obj.url:
obj.url = translit_with_separator(obj.name)
# try:
obj.save()
# except IntegrityError, e:
# error = str(e)
# if typical_errors.get(error):
# error = typical_errors[error]
# if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'):
#
# error = u'Событие с таким названием или урлом уже существует'
#
# errors.append([obj.name, error])
# log_msg += error
# logcall(log.log, log_msg + '\n')
# continue
for method in methods:
func = method['func']
if method.get('purpose'):
try:
func(obj, method['value'], method['purpose'])
except:
#log_msg += '(%s: Ошибка);'%method['field']
continue
else:
msg = func(obj, method['value'])
if msg:
#log_msg += '(%s: %s);'%(method['field'], msg)
pass
#logcall(log.log, log_msg + '\n')
def save_file(self):
data = self.cleaned_data
lang = data['language']
@ -234,27 +358,10 @@ class ImportPlaceExpositionForm(ImportForm):
return errors
class ImportPlaceConferenceForm(ImportForm):
class ImportPlaceConferenceForm(ImportPlaceExpositionForm):
model = PlaceConference
from import_xls.excel_settings import event_sett
typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'country_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата окончания',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
# event
import time
def logcall(f, msg):
with open(f.file.name, 'a') as logfile:
logfile.write(msg.encode('utf8'))
from import_xls.models import Log
class ImportEventForm(ImportForm):
"""
extended form for importing one type of event
@ -359,8 +466,8 @@ class ImportEventForm(ImportForm):
except Exception:
setattr(obj, 'place_alt', cell)
if not obj.url:
a = obj.name
obj.url = translit_with_separator(obj.name)
obj.is_published = True
try:
obj.save()

@ -189,6 +189,63 @@ def conference_change(request, url):
return render_to_response('place_conference_add.html', args)
from photologue.forms import PhotoForm
from functions.admin_views import AdminView
from file.forms import FileModelForm, FileForm
class PlaceConferenceView(AdminView):
form_class = ConferenceForm
model = PlaceConference
success_url = '/admin/place_conference/all/'
template_name = 'admin/place_conference/place_conference.html'
def get_form(self, form_class):
if self.request.POST:
return super(PlaceConferenceView, self).get_form(form_class)
obj = self.set_obj()
if obj:
data = {'type': obj.type, 'address': obj.address,
'phone': obj.phone, 'fax': obj.fax, 'web_page': obj.web_page, 'email': obj.email,
'foundation_year': obj.foundation_year, 'total_capacity': obj.total_capacity,
'amount_halls': obj.amount_halls, 'wifi':obj.wifi, 'multimedia_equipment': obj.multimedia_equipment,
'conference_call':obj.conference_call, 'translate_equipment': obj.translate_equipment,
'banquet_hall': obj.banquet_hall, 'catering': obj.catering, 'hotel': obj.hotel,
'video_link':obj.video_link, 'logo': obj.logo, 'exposition_hall': obj.exposition_hall,
'exp_hall_area': obj.exp_hall_area}
data['country'] = obj.country_id
data['city'] = obj.city_id
for code, name in settings.LANGUAGES:
trans_obj = self.model._meta.translations_model.objects.get(language_code = code,master__id=obj.id) #access to translated fields
data['name_%s'%code] = obj.name
data['main_title_%s'%code] = obj.main_title
data['description_%s'%code] = obj.description
data['adress_%s'%code] = obj.adress
data['hall_capacity_%s'%code] = obj.hall_capacity
data['title_%s'%code] = obj.title
data['keywords_%s'%code] = obj.keywords
data['descriptions_%s'%code] = obj.descriptions
data['total_year_action_%s'%code] = obj.total_year_action
form = form_class(initial=data)
form.fields['city'].widget.attrs['data-init-text'] = obj.city.name
return form
else:
return form_class()
def get_context_data(self, **kwargs):
context = super(PlaceConferenceView, self).get_context_data(**kwargs)
obj = self.set_obj()
if obj:
context['file_form'] = FileForm(initial={'model': 'place_conference.PlaceConference'})
files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id'))
context['files'] = files
context['photo_form'] = PhotoForm()
return context
class PlaceConferenceListView(AdminListView):
template_name = 'admin/place_conference/place_conference_list.html'
form_class = PlaceConferenceFilterForm

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from admin import PlaceConferenceListView
from admin import PlaceConferenceListView, PlaceConferenceView
urlpatterns = patterns('place_conference.admin',
url(r'^add.*/$', 'conference_add'),
@ -9,4 +9,6 @@ urlpatterns = patterns('place_conference.admin',
url(r'^copy/(?P<url>.*)/$', 'place_conference_copy'),
#url(r'^all/$', 'conference_all'),
url(r'^all/$', PlaceConferenceListView.as_view()),
url(r'^(?P<url>.*)/$', PlaceConferenceView.as_view()),
url(r'^$', PlaceConferenceView.as_view()),
)

@ -28,12 +28,12 @@ class ConferenceForm(forms.Form):
"""
types = [(item1, item2) for item1, item2 in CONFERENCE_TYPE]
type = forms.ChoiceField(label='Краткое описание', required=False, choices=types)
logo = forms.ImageField(label='Logo', required=False, max_length=500)
country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None)
#creates select input with empty choices cause it will be filled with ajax
city = forms.ChoiceField(label='Город', choices=[('','')])
city = forms.CharField(label='Город', widget=forms.HiddenInput())
address = forms.CharField(label='Адресс', widget=LocationWidget)
address = forms.CharField(label='Адресс', widget=LocationWidget, required=False)
foundation_year = forms.CharField(label='Год основания', required=False,
widget=forms.TextInput(attrs={'placeholder': 'Год основания'}))
phone = forms.CharField(label='Телефон', required=False,
@ -108,7 +108,7 @@ class ConferenceForm(forms.Form):
"""
def save(self, id=None):
def save(self, obj=None):
"""
change PlaceConference model object with id = id
N/A add new PlaceConference model object
@ -117,13 +117,20 @@ class ConferenceForm(forms.Form):
"""
data = self.cleaned_data
#create new place_conference object or get exists
if not id:
if not obj:
place_conference = PlaceConference()
else:
place_conference = PlaceConference.objects.get(id=id)
place_conference = obj
if not getattr(place_conference, 'url'):
if data.get('name_en'):
place_conference.url = translit_with_separator(data['name_en'].strip()).lower()
else:
place_conference.url = translit_with_separator(data['name_ru'].strip()).lower()
if data.get('logo'):
place_conference.logo = data['logo']
#simple fields
place_conference.url = translit_with_separator(data['name_ru'].strip()).lower()
place_conference.type = data['type']
place_conference.address = data['address']
place_conference.phone = data['phone']
@ -152,22 +159,9 @@ class ConferenceForm(forms.Form):
fill_with_signal(PlaceConference, place_conference, data)
#save files
check_tmp_files(place_conference, data['key'])
return PlaceConference.objects.get(id=place_conference.id)
def clean(self):
id = self.cleaned_data.get('place_conference_id')
name_ru = self.cleaned_data.get('name_ru')
place_conference = PlaceConference.objects.filter(url=translit_with_separator(name_ru))
if place_conference and str(place_conference[0].id) != id:
msg = 'Место проведения с таким названием уже существует'
self._errors['name_ru'] = ErrorList([msg])
del self.cleaned_data['name_ru']
return self.cleaned_data
place_conference.save()
return place_conference
def clean_web_page(self):
"""
@ -318,4 +312,17 @@ class HallForm(forms.ModelForm):
class PlaceConferenceFilterForm(AdminFilterForm):
model = PlaceConference
model = PlaceConference
country = forms.MultipleChoiceField(choices=[(item.id, item.name) for item in list(Country.objects.all())],
required=False, widget=forms.SelectMultiple())
def filter(self):
qs = super(PlaceConferenceFilterForm, self).filter()
data = self.cleaned_data
country = data['country']
if country:
qs = qs.filter(country_id__in=country)
return qs

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.contenttypes import generic
from django.db.models.signals import post_save
from django.db.models.signals import post_save, pre_save
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from functions.custom_fields import EnumField
from functions.custom_fields import LocationField
from functions.signal_handlers import post_save_handler
from functions.signal_handlers import post_save_handler, pre_save_handler
from functions.models_methods import ExpoManager
import copy
from django.utils.translation import ugettext as _
@ -15,6 +15,11 @@ from functions.model_mixin import ExpoMixin
CONFERENCE_TYPE = (('Convention centre', 'Конгресс-центр'), ('Exposition centre', 'Конференц зал'),)
def logo_name(instance, filename):
url = instance.url
return '/'.join(['place_conference', url, url+'_logo.jpg'])
class PlaceConference(TranslatableModel, ExpoMixin):
"""
Create PlaceConference model
@ -22,28 +27,33 @@ class PlaceConference(TranslatableModel, ExpoMixin):
Uses hvad.TranslatableModel which is child of django.db.models class
"""
#set manager of this model
catalog = '/places/'
place = 'place_conference'
catalog_name = _(u'Места:')
search_name = None
objects = ExpoManager()
url = models.SlugField(unique=True)
country = models.ForeignKey('country.Country', on_delete=models.PROTECT)
city = models.ForeignKey('city.City', on_delete=models.PROTECT, related_name='place_conferences')
country = models.ForeignKey('country.Country', on_delete=models.PROTECT, verbose_name=_(u'Страна'))
city = models.ForeignKey('city.City', on_delete=models.PROTECT,
related_name='place_conferences', verbose_name=_(u'Город'))
#type uses EnumField for creating Enum type field in Mysql database
type = EnumField(values = [item1 for item1, item2 in CONFERENCE_TYPE])
type = EnumField(values = [item1 for item1, item2 in CONFERENCE_TYPE], default=CONFERENCE_TYPE[0][0],
verbose_name=_(u'Тип'))
#information
address = LocationField(verbose_name=_(u'Адресс'))
#
address= LocationField(verbose_name='Адресс')
#
phone = models.BigIntegerField(blank=True, null=True)
fax = models.BigIntegerField(blank=True, null=True)
web_page = models.URLField(blank=True)
email = models.EmailField(blank=True)
foundation_year = models.PositiveIntegerField(blank=True, null=True)
total_capacity = models.PositiveIntegerField(blank=True, null=True)
amount_halls = models.PositiveIntegerField(blank=True, null=True)
exposition_hall = models.NullBooleanField()
exp_hall_area = models.PositiveIntegerField(blank=True, null=True)
phone = models.BigIntegerField(blank=True, null=True, verbose_name=_(u'Телефон'))
fax = models.BigIntegerField(blank=True, null=True, verbose_name=_(u'Факс'))
web_page = models.URLField(blank=True, verbose_name=_(u'Веб сайт'))
email = models.EmailField(blank=True, verbose_name=_(u'Email'))
foundation_year = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Год основания'))
total_capacity = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Общая вместимость'))
amount_halls = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Количество залов'))
exposition_hall = models.NullBooleanField(verbose_name=_(u'Выставочный зал'))
exp_hall_area = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Площадь выст. зала'))
video_link = models.CharField(max_length=255, blank=True)
virtual_tour = models.URLField(blank=True, verbose_name=_(u'Виртуальный тур'))
#
wifi = models.NullBooleanField()
multimedia_equipment = models.NullBooleanField()
@ -53,6 +63,7 @@ class PlaceConference(TranslatableModel, ExpoMixin):
catering = models.NullBooleanField()
hotel = models.NullBooleanField()
#
logo = models.ImageField(verbose_name='Logo', upload_to=logo_name, blank=True, max_length=255)
files = generic.GenericRelation('file.FileModel',content_type_field='content_type', object_id_field='object_id')
#translations is translated fields
translations = TranslatedFields(
@ -162,5 +173,5 @@ class Hall(models.Model):
number = models.PositiveIntegerField(blank=True, null=True)
capacity = models.PositiveIntegerField(blank=True, null=True)
pre_save.connect(pre_save_handler, sender=PlaceConference)
post_save.connect(post_save_handler, sender=PlaceConference)

@ -112,7 +112,7 @@ class ExpositionForm(forms.Form):
else:
place_exposition = obj
#simple fields
if not getattr(place_exposition, 'url'):
if data.get('name_en'):
place_exposition.url = translit_with_separator(data['name_en'].strip()).lower()
@ -252,30 +252,6 @@ class PlaceExpositionFormDelete(forms.ModelForm):
model = PlaceExposition
fields = ('url',)
'''
class HallForm(forms.ModelForm):
"""
form for Hall model
uses ModelForm cause Hall doesnt have translated fields
"""
number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:30px'}),required=False)
capacity = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:60px'}), required=False)
name = forms.CharField(required=False)
class Meta:
model = Hall
exclude = ('place_exposition',)
def clean_number(self):
cleaned_data = super(HallForm, self).clean()
number = cleaned_data.get('number').strip()
return is_positive_integer(number, 'Номер должен состоять из цифр')
def clean_capacity(self):
cleaned_data = super(HallForm, self).clean()
capacity = cleaned_data.get('capacity').strip()
return is_positive_integer(capacity, 'Вместимость должна состоять из цифр')
'''
class HallForm(forms.Form):
url = '/admin/place_exposition/add-hall/'

@ -39,6 +39,7 @@ class PlaceExposition(TranslatableModel, ExpoMixin):
"""
catalog = '/places/'
place = 'place_exposition'
catalog_name = _(u'Места:')
search_name = None
#set manager of this model
@ -289,17 +290,3 @@ def create_place(sender, instance, created, **kwargs):
pre_save.connect(pre_save_handler, sender=PlaceExposition)
post_save.connect(create_place, sender=PlaceExposition)
post_save.connect(post_save_handler, sender=Hall)
"""
def calculate_rating_for_translations(sender, instance, created, **kwargs):
company = instance.master
post_save.disconnect(calculate_rating_for_translations, sender=Company._meta.translations_model)
calculate_rating(company)
post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model)
post_save.connect(create_company, sender=Company)
post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model)
"""

@ -80,7 +80,7 @@ class PlaceDetail(JitterCacheMixin, MetadataMixin, DetailView):
obj = queryset.get()
except queryset.model.DoesNotExist:
try:
PlaceConference.objects.get(url=slug)
obj = PlaceConference.objects.get(url=slug)
except PlaceConference.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %

@ -66,11 +66,8 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-circle-arrow-down"></i> Импорт<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/admin/import-event">События</a></li>
<li><a href="/admin/import-organiser">Организаторы</a></li>
<li><a href="/admin/import-place_exposition">Место проведения выставок</a></li>
<li><a href="/admin/import-place_conference">Место проведения конференций</a></li>
<li><a href="/admin/import-theme">Тематики</a></li>
<li><a href="/admin/import-tag">Теги</a></li>
</ul>
</li>
@ -78,12 +75,11 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class=" icon-circle-arrow-up"></i> Экспорт<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/admin/export-event">События</a></li>
<li><a href="/admin/export-organiser">Организаторы</a></li>
<li><a href="/admin/export-place_exposition">Место проведения выставок</a></li>
<li><a href="/admin/export-place_conference">Место проведения конференций</a></li>
<li><a href="/admin/export-theme">Тематики</a></li>
<li><a href="/admin/export-tag">Теги</a></li>
<li><a href="/admin/export-user">Пользователи</a></li>
<li><a href="/admin/export-company">Компании</a></li>
</ul>
</li>

@ -0,0 +1,340 @@
{% extends 'base.html' %}
{% load static %}
{% block styles %}
.hover{
display:none;
margin-bottom:10px;
}
.photo:hover .hover {
display: block;
}
{% endblock %}
{% block scripts %}
<script src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script>
{# google map не забыть скачать скрипты на локал #}
<link href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/redmond/jquery-ui.css' rel="stylesheet"/>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js'></script>
<script src='http://maps.google.com/maps/api/js?sensor=false'></script>
{# selects #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<script src="{% static 'js/select/select2.js' %}"></script>
<script src="{% static 'custom_js/make_select.js' %}"></script>
<script src="{% static 'custom_js/formset_add.js' %}"></script>
{# ajax #}
<!-- <script src="{% static 'custom_js/file_post_ajax.js' %}"></script>-->
<script src="{% static 'custom_js/place_city_ajax.js' %}"></script>
{% endblock %}
{% block body %}
<form method="post" class="form-horizontal" enctype="multipart/form-data" name="form1" id="form1"> {% csrf_token %}
<fieldset>
<legend><i class="icon-edit"></i> {% if object %} Изменить {% else %} Добавить {% endif %}место{% if object %}(<a target="_blank" href="{{ object.get_permanent_url }}">на сайте</a>){% endif %}</legend>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i> Основная информация</h2>
</div>
<div class="box-content">
{# name #}
{% with field='name' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# type #}
<div class="control-group {% if form.type.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.type.label }}:</b></label>
<div class="controls">{{ form.type}}
<span class="help-inline">{{ form.type.errors }}</span>
</div>
</div>
{# main_title #}
{% with field='main_title' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# country #}
<div class="control-group {% if form.country.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.country.label }}:</b></label>
<div class="controls">{{ form.country }}
<span class="help-inline">{{ form.country.errors }}</span>
</div>
</div>
{# city #}
<div class="control-group {% if form.city.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.city.label }}:</b></label>
<div class="controls">{{ form.city }}
<span class="help-inline">{{ form.city.errors }}</span>
</div>
</div>
{# logo #}
<div class="control-group {% if form.logo.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.logo.label }}:</b></label>
<div class="controls">{{ form.logo }}
<span class="help-inline">{{ form.logo.errors }}</span>
</div>
</div>
</div>
</div>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i> Дополнительная информация</h2>
</div>
<div class="box-content">
{# description #}
{% with field='description' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# adress #}
{% with field='adress' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# address #}
<div class="control-group {% if form.address.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.address.label }}:</b></label>
<div class="controls">{{ form.address }}
<span class="help-inline">{{ form.address.errors }}</span>
</div>
</div>
{# phone #}
<div class="control-group {% if form.phone.errors %}error{% endif %}">
<label class="control-label">{{ form.phone.label }}:</label>
<div class="controls">{{ form.phone}}
<span class="help-inline">{{ form.phone.errors }}</span>
</div>
</div>
{# fax #}
<div class="control-group {% if form.fax.errors %}error{% endif %}">
<label class="control-label">{{ form.fax.label }}:</label>
<div class="controls">{{ form.fax}}
<span class="help-inline">{{ form.fax.errors }}</span>
</div>
</div>
{# web_page #}
<div class="control-group {% if form.web_page.errors %}error{% endif %}">
<label class="control-label">{{ form.web_page.label }}:</label>
<div class="controls">{{ form.web_page}}
<span class="help-inline">{{ form.web_page.errors }}</span>
</div>
</div>
{# email #}
<div class="control-group {% if form.email.errors %}error{% endif %}">
<label class="control-label">{{ form.email.label }}:</label>
<div class="controls">{{ form.email}}
<span class="help-inline">{{ form.email.errors }}</span>
</div>
</div>
</div>
</div>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i> Основная информация</h2>
</div>
<div class="box-content">
{# foundation_year #}
<div class="control-group {% if form.foundation_year.errors %}error{% endif %}">
<label class="control-label">{{ form.foundation_year.label }}:</label>
<div class="controls">{{ form.foundation_year}}
<span class="help-inline">{{ form.foundation_year.errors }}</span>
</div>
</div>
{# total_year_action #}
{% with field='total_year_action' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# total_capacity #}
<div class="control-group {% if form.total_capacity.errors %}error{% endif %}">
<label class="control-label">{{ form.total_capacity.label }}:</label>
<div class="controls">{{ form.total_capacity}}
<span class="help-inline">{{ form.total_capacity.errors }}</span>
</div>
</div>
{# amount_halls #}
<div class="control-group {% if form.amount_halls.errors %}error{% endif %}">
<label class="control-label">{{ form.amount_halls.label }}:</label>
<div class="controls">{{ form.amount_halls}}
<span class="help-inline">{{ form.amount_halls.errors }}</span>
</div>
</div>
{# video_link #}
<div class="control-group {% if form.video_link.errors %}error{% endif %}">
<label class="control-label">{{ form.video_link.label }}:</label>
<div class="controls">{{ form.video_link}}
<span class="help-inline">{{ form.video_link.errors }}</span>
</div>
</div>
{# exp_hall_area #}
<div class="control-group {% if form.exp_hall_area.errors %}error{% endif %}">
<label class="control-label">{{ form.exp_hall_area.label }}:</label>
<div class="controls">{{ form.exp_hall_area}}
<span class="help-inline">{{ form.exp_hall_area.errors }}</span>
</div>
</div>
</div>
</div>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i> Услуги</h2>
</div>
<div class="box-content">
<div style="float: left">
{# exposition_hall #}
<div class="control-group {% if form.exposition_hall.errors %}error{% endif %}">
<label class="control-label">{{ form.exposition_hall.label }}:</label>
<div class="controls">{{ form.exposition_hall}}
<span class="help-inline">{{ form.exposition_hall.errors }}</span>
</div>
</div>
{# wifi #}
<div class="control-group {% if form.wifi.errors %}error{% endif %}">
<label class="control-label">{{ form.wifi.label }}:</label>
<div class="controls">{{ form.wifi}}
<span class="help-inline">{{ form.wifi.errors }}</span>
</div>
</div>
{# catering #}
<div class="control-group {% if form.catering.errors %}error{% endif %}">
<label class="control-label">{{ form.catering.label }}:</label>
<div class="controls">{{ form.catering}}
<span class="help-inline">{{ form.catering.errors }}</span>
</div>
</div>
{# hotel #}
<div class="control-group {% if form.hotel.errors %}error{% endif %}">
<label class="control-label">{{ form.hotel.label }}:</label>
<div class="controls">{{ form.hotel}}
<span class="help-inline">{{ form.hotel.errors }}</span>
</div>
</div>
{# banquet_hall #}
<div class="control-group {% if form.banquet_hall.errors %}error{% endif %}">
<label class="control-label">{{ form.banquet_hall.label }}:</label>
<div class="controls">{{ form.banquet_hall}}
<span class="help-inline">{{ form.banquet_hall.errors }}</span>
</div>
</div>
</div>
<div style="float: left" class="offset1">
{# multimedia_equipment #}
<div class="control-group {% if form.multimedia_equipment.errors %}error{% endif %}">
<label class="control-label">{{ form.multimedia_equipment.label }}:</label>
<div class="controls">{{ form.multimedia_equipment}}
<span class="help-inline">{{ form.multimedia_equipment.errors }}</span>
</div>
</div>
{# translate_equipment #}
<div class="control-group {% if form.translate_equipment.errors %}error{% endif %}">
<label class="control-label">{{ form.translate_equipment.label }}:</label>
<div class="controls">{{ form.translate_equipment}}
<span class="help-inline">{{ form.translate_equipment.errors }}</span>
</div>
</div>
{# conference_call #}
<div class="control-group {% if form.conference_call.errors %}error{% endif %}">
<label class="control-label">{{ form.conference_call.label }}:</label>
<div class="controls">{{ form.conference_call}}
<span class="help-inline">{{ form.conference_call.errors }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="box span8" id="file">
<div class="box-header well">
<h2><i class="icon-pencil"></i> Файлы</h2>
</div>
<div class="box-content">
{% if object %}
{# button that shows modal window with file form #}
<a href="#myModal" id="file_add" role="button" class="btn btn-info" data-toggle="modal">Добавить файл</a>
{% else %}
<p>Файлы можно добавлять только после введения основных данных</p>
{% endif %}
{# this div shows list of files and refreshes when new file added #}
<div id="file_list">
<table class="table table-hover">
<thead>
<tr>
<td>id</td>
<td>Файл</td>
<td>Имя</td>
<td>Назначение</td>
<td></td>
</tr>
</thead>
<tbody>
{% include 'file_list.html' with files=files %}
</tbody>
</table>
</div>
</div>
</div>
{% include 'admin/includes/photogallery.html' with object=object %}
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i> Мета данные</h2>
</div>
<div class="box-content">
{# keywords #}
{% with field='keywords' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# title #}
{% with field='title' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# descriptions #}
{% with field='descriptions' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% endwith %}
</div>
</div>
<div class="controls">
<input class="btn btn-large btn-primary" type="submit" value="Добавить">
<input class="btn btn-large" type="reset" value="Отмена">
</div>
</fieldset>
</form>
{% include 'admin/includes/hall_form.html' with form=hall_form object=object %}
{% include 'admin/includes/photo_form.html' with form=photo_form object=object %}
{% include 'admin/includes/file_form.html' with file_form=file_form object=object %}
{% endblock %}

@ -38,7 +38,7 @@
<td>{% ifnotequal item.country None %}{{ item.country }} {% endifnotequal %}</td>
<td>{% ifnotequal item.city None %}{{ item.city }} {% endifnotequal %}</td>
<td class="center sorting_1">
<a class="btn-small btn-info" href="/admin/place_conference/change/{{ item.url|lower }}">
<a class="btn-small btn-info" href="/admin/place_conference/{{ item.url|lower }}/">
Изменить
</a>
</td>

@ -0,0 +1,86 @@
{% load i18n %}
{% load template_filters %}
<div class="e-num-info">
{% if place.place == 'place_exposition' %}
{% if place.total_area %}
<div class="eni-area-wrap">
<div class="eni-title">{% trans 'Общая выставочная площадь' %}</div>
<div class="eni-area">{{ place.total_area|int_format }} м²</div>
</div>
{% endif %}
{% else %}
{% comment %}
{% if place.total_capacity %}
<div class="eni-area-wrap">
<div class="eni-title">{% trans 'Общая вместимость' %}</div>
<div class="eni-area">{{ place.total_capacity|int_format }}</div>
</div>
{% endif %}
{% endcomment %}
{% endif %}
<div class="eni-areas clearfix">
{% if place.closed_area %}
<div class="enis-col">
<b>{{ place.closed_area|int_format }} {% trans 'м²' %}</b>
{% trans 'закрытая выставочная площадь' %}
</div>
{% endif %}
{% if place.open_area %}
<div class="enis-col">
<b>{{ place.open_area|int_format }} {% trans 'м²' %}</b>
{% trans 'открытая выставочная площадь' %}
</div>
{% endif %}
</div>
<div class="eni-areas clearfix">
<div class="enis-col">
<ul>
{% for hall in place.halls.all %}
{% if not forloop.counter|divisibleby:"2" %}
<li>{{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м<sup>2</sup></li>
{% endif %}
{% endfor %}
</ul>
</div>
<div class="enis-col">
<ul>
{% for hall in place.halls.all %}
{% if forloop.counter|divisibleby:"2" %}
<li>{{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м<sup>2</sup></li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
{% if place.total_year_action %}
<div class="eni-areas stat clearfix">
<div class="eni-title">
{% trans 'Ежегодно проводится' %}
</div>
<div class="enis-col">
{% if place.total_year_action.isdigit %}
{% ifequal LANGUAGE_CODE 'ru' %}
{% load pymorphy_tags %}
<b>{{ place.total_year_action }}</b>
{{ "событие"|plural:place.total_year_action }}
{% else %}
<b>{{ place.total_year_action }}</b>
{% trans 'событий' %}
{% endifequal %}
{% else %}
<b>{{ place.total_year_action }}</b>
{% endif %}
</div>
</div>
{% endif %}
{% if place.foundation_year %}
<div class="eni-areas">
<div class="eni-founded">{% trans 'Основано в' %} <b>{{ place.foundation_year }}</b> {% trans 'году' %}</div>
</div>
{% endif %}
</div>

@ -27,10 +27,10 @@
<div class="address">
{{ place.adress }}
</div>
<div class="show-map"><a class="toggle-map" href="#">Раскрыть карту</a></div>
<div class="show-map"><a class="toggle-map" href="#">{% trans 'Раскрыть карту' %}</a></div>
</header>
<div class="i-map ">
<div class="close-map"><a class="toggle-map" href="#">Скрыть карту</a></div>
<div class="close-map"><a class="toggle-map" href="#">{% trans 'Скрыть карту' %}</a></div>
<!-- позиция для карты задается в атрибуте data-coords -->
<div class="map-canvas" id="map-canvas" data-coords="{{ place.address.lat|stringformat:'f' }},{{ place.address.lng|stringformat:'f' }}" ></div>
</div>
@ -41,53 +41,7 @@
</div>
</div>
</div>
<div class="i-services">
<div class="sect-title">Услуги</div>
<div class="is-wrap clearfix">
<ul>
{% if place.bank %}
<li>{% trans 'Банк / банкоматы / обмен валюты' %}</li>
{% endif %}
{% if place.wifi %}
<li>Wi-Fi</li>
{% endif %}
{% if place.children_room %}
<li>{% trans 'Детская комната' %}</li>
{% endif %}
{% if place.disabled_service %}
<li>{% trans 'Сервис для инвалидов' %}</li>
{% endif %}
</ul>
<ul>
{% if place.conference_centre %}
<li>{% trans 'Конгресс-центр' %}</li>
{% endif %}
{% if place.business_centre %}
<li>{% trans 'Бизнес-центр' %}</li>
{% endif %}
{% if place.online_registration %}
<li>{% trans 'Онлайн-регистрация' %}</li>
{% endif %}
{% if place.cafe %}
<li>{% trans 'Кафе и рестораны' %}</li>
{% endif %}
</ul>
<ul>
{% if place.terminals %}
<li>{% trans 'Информационные терминалы' %}</li>
{% endif %}
{% if place.parking %}
<li>{% trans 'Парковка' %}</li>
{% endif %}
{% if place.press_centre %}
<li>{% trans 'Пресс-центр' %}</li>
{% endif %}
{% if place.mobile_application %}
<li>{% trans 'Мобильное приложение' %}</li>
{% endif %}
</ul>
</div>
</div>
{% include 'client/includes/place/place_services.html' with place=place %}
<hr />
{% if place.photogallery %}
{% with photos=place.photogallery.photos.all|slice:"5" %}
@ -109,228 +63,162 @@
</div>
{% endwith %}
{% endif %}
<div class="e-num-info">
{% if place.total_area %}
<div class="eni-area-wrap">
<div class="eni-title">{% trans 'Общая выставочная площадь' %}</div>
<div class="eni-area">{{ place.total_area|int_format }} м²</div>
</div>
{% endif %}
<div class="eni-areas clearfix">
{% if place.closed_area %}
<div class="enis-col">
<b>{{ place.closed_area|int_format }} {% trans 'м²' %}</b>
{% trans 'закрытая выставочная площадь' %}
</div>
{% endif %}
{% if place.open_area %}
<div class="enis-col">
<b>{{ place.open_area|int_format }} {% trans 'м²' %}</b>
{% trans 'открытая выставочная площадь' %}
</div>
{% endif %}
</div>
<div class="eni-areas clearfix">
<div class="enis-col">
<ul>
{% for hall in place.halls.all %}
{% if not forloop.counter|divisibleby:"2" %}
<li>{{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м<sup>2</sup></li>
{% endif %}
{% endfor %}
</ul>
</div>
<div class="enis-col">
<ul>
{% for hall in place.halls.all %}
{% if forloop.counter|divisibleby:"2" %}
<li>{{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м<sup>2</sup></li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
{% if place.total_year_action %}
<div class="eni-areas stat clearfix">
<div class="eni-title">
{% trans 'Ежегодно проводится' %}
</div>
<div class="enis-col">
{% if place.total_year_action.isdigit %}
{% ifequal LANGUAGE_CODE 'ru' %}
{% load pymorphy_tags %}
<b>{{ place.total_year_action }}</b>
{{ "событие"|plural:place.total_year_action }}
{% else %}
<b>{{ place.total_year_action }}</b>
{% trans 'событий' %}
{% endifequal %}
{% include 'client/includes/place/place_info.html' with place=place %}
{% if place.get_scheme %}
<hr />
<div class="e-pv-container">
<div class="sect-title">{% trans 'Схема павильонов' %}</div>
{% for scheme in place.get_scheme %}
{% ifequal scheme.file_path.url|slice:"-3:" 'pdf' %}
<a href="{{ scheme.file_path.url }}">{% trans 'Схема в pdf' %}</a>
{% else %}
<b>{{ place.total_year_action }}</b>
{% endif %}
</div>
<div class="div-img-wrap"><img src="{{ scheme.file_path.url }}" alt="" /></div>
{% endifequal %}
<hr/>
{% endfor %}
</div>
{% endif %}
{% if place.foundation_year %}
<div class="eni-areas">
<div class="eni-founded">{% trans 'Основано в' %} <b>{{ place.foundation_year }}</b> {% trans 'году' %}</div>
</div>
{% endif %}
</div>
{% if place.get_scheme %}
<hr />
<div class="e-pv-container">
<div class="sect-title">{% trans 'Схема павильонов' %}</div>
{% for scheme in place.get_scheme %}
{% ifequal scheme.file_path.url|slice:"-3:" 'pdf' %}
<a href="{{ scheme.file_path.url }}">{% trans 'Схема в pdf' %}</a>
{% else %}
<div class="div-img-wrap"><img src="{{ scheme.file_path.url }}" alt="" /></div>
{% endifequal %}
<hr/>
{% endfor %}
</div>
{% endif %}
<div class="i-contacts clearfix">
<div class="sect-title">{% trans 'Контактная информация' %}</div>
<div class="ic-wrap">
<div class="ic-col">
<div class="ic-addr">{{ place.adress }}</div>
<div class="ic-links">
<a target="_blank" href="#" data-type="href" data-hash="1qwer" data-url="{{ place.web_page|base64_encode }}" class="link-encode">{{ place.web_page }}</a>
<div class="i-contacts clearfix">
<div class="sect-title">{% trans 'Контактная информация' %}</div>
<div class="ic-wrap">
<div class="ic-col">
<div class="ic-addr">{{ place.adress }}</div>
<div class="ic-links">
<a target="_blank" href="#" data-type="href" data-hash="1qwer" data-url="{{ place.web_page|base64_encode }}" class="link-encode">{{ place.web_page }}</a>
</div>
</div>
<div class="ic-col">
<ul class="tels">
{% if place.phone %}
<li>{{ place.phone|phone }} ({% trans 'телефон' %})</li>
{% endif %}
{% if place.fax %}
<li>{{ place.fax|phone }} ({% trans 'факс' %})</li>
{% endif %}
</ul>
</div>
</div>
<div class="ic-col">
<ul class="tels">
{% if place.phone %}
<li>{{ place.phone|phone }} ({% trans 'телефон' %})</li>
{% endif %}
{% if place.fax %}
<li>{{ place.fax|phone }} ({% trans 'факс' %})</li>
{% endif %}
</ul>
</div>
</div>
</div>
{% if place.events %}
<div class="i-events-list">
<div class="sect-title">{% trans 'Список событий' %}</div>
<ul class="cat-list cl-exhibitions">
{% for event in place.events %}
<li class="cl-item" data-link="#">
<div class="cl-item-wrap clearfix">
<a href="{{ event.get_permanent_url }}">
{% if event.expohit %}
<span class="hit"></span>
{% endif %}
<div class="cli-pict">
{% with obj=event %}
{% include 'show_logo.html' %}
{% endwith %}
</div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title"><a href="{{ event.get_permanent_url }}">{{ event.name|safe }}</a></div>
</header>
<div class="cli-bot clearfix">
<div class="cli-date">
{% with obj=event %}
{% include 'show_date_block.html' %}
{% endwith %}
</div>
<div class="cli-place">
<a href="{{ event.catalog }}country/{{ event.country.url }}/">{{ event.country }}</a>, <a href="{{ event.catalog }}city/{{ event.city.url }}/">{{ event.city }}</a>
</div>
</div>
</div>
</div>
<div class="cli-buttons clearfix">
<div class="cli-m-buttons">
<div class="cli-services">
<a class="button icon-sm" href="#">{% trans 'услуги' %}</a>
<div class="cli-services-sm">
<ul>
{% for service in event.get_services %}
<li><a href="{{ service.get_permanent_url }}">{{ service.name }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<a class="button blue icon-calendar" href="{{ event.get_calendar_url }}">{% trans 'в расписание' %}</a>
<a class="button green icon-note" href="#">заметка</a>
</div>
<div class="cli-s-buttons">
<a class="button blue2 lc" target="_blank" href="http://www.booking.com/searchresults.html?aid={{ book_aid }}&city={{ event.city.id }}">{% trans 'Лучшие цены на отели на' %} <i>Booking</i>.com</a>
</div>
{% if place.events %}
<div class="i-events-list">
<div class="sect-title">{% trans 'Список событий' %}</div>
<ul class="cat-list cl-exhibitions">
{% for event in place.events %}
<li class="cl-item" data-link="#">
<div class="cl-item-wrap clearfix">
<a href="{{ event.get_permanent_url }}">
{% if event.expohit %}
<span class="hit"></span>
{% endif %}
<div class="cli-pict">
{% with obj=event %}
{% include 'show_logo.html' %}
{% endwith %}
</div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title"><a href="{{ event.get_permanent_url }}">{{ event.name|safe }}</a></div>
</header>
<div class="cli-bot clearfix">
<div class="cli-date">
{% with obj=event %}
{% include 'show_date_block.html' %}
{% endwith %}
</div>
<div class="cli-place">
<a href="{{ event.catalog }}country/{{ event.country.url }}/">{{ event.country }}</a>, <a href="{{ event.catalog }}city/{{ event.city.url }}/">{{ event.city }}</a>
</div>
</div>
</div>
</div>
<div class="cli-buttons clearfix">
<div class="cli-m-buttons">
<div class="cli-services">
<a class="button icon-sm" href="#">{% trans 'услуги' %}</a>
<div class="cli-services-sm">
<ul>
{% for service in event.get_services %}
<li><a href="{{ service.get_permanent_url }}">{{ service.name }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<a class="button blue icon-calendar" href="{{ event.get_calendar_url }}">{% trans 'в расписание' %}</a>
<a class="button green icon-note" href="#">{% trans 'заметка' %}</a>
</div>
<div class="cli-s-buttons">
<a class="button blue2 lc" target="_blank" href="http://www.booking.com/searchresults.html?aid={{ book_aid }}&city={{ event.city.id }}">{% trans 'Лучшие цены на отели на' %} <i>Booking</i>.com</a>
</div>
</div>
</div>
<footer class="clearfix">
<div class="cli-stats">
{% if event.visitors %}<span class="visitors"> {{ event.visitors }}</span>{% endif %}
{% if event.members %}<span class="participants">{{ event.members }}</span>{% endif %}
</div>
<div class="cli-tags">
{% include 'client/includes/exposition/tags.html' with obj=event %}
</div>
</div>
<footer class="clearfix">
<div class="cli-stats">
{% if event.visitors %}<span class="visitors"> {{ event.visitors }}</span>{% endif %}
{% if event.members %}<span class="participants">{{ event.members }}</span>{% endif %}
</div>
<div class="cli-tags">
{% include 'client/includes/exposition/tags.html' with obj=event %}
</div>
</footer>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="m-article">
{% include 'client/includes/booking_block.html' with city=place.city place=place %}
</div>
<div class="clearfix">
<hr />
{% include 'client/includes/banners/detail_inner.html' %}
</div>
{% if place.get_nearest_places %}
<div class="e-cat">
<div class="sect-title">{% trans 'Ближайшие выставочные центры' %}</div>
<ul class="cat-list cl-places">
{% for pl in place.get_nearest_places %}
<li class="cl-item">
<div class="cl-item-wrap clearfix">
<a href="{{ pl.get_permanent_url }}">
<div class="cli-pict">
{% include 'show_logo.html' with obj=pl %}
</div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title">
<a href="{{ pl.get_permanent_url }}"> {{ pl.name|safe }}</a>
</div>
<!--<div class="cli-rate">{{ pl.rating }}</div>-->
</header>
<div class="cli-descr">{{ pl.get_type }}</div>
</div>
</footer>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="m-article">
{% include 'client/includes/booking_block.html' with city=place.city place=place %}
</div>
<div class="clearfix">
<hr />
{% include 'client/includes/banners/detail_inner.html' %}
</div>
{% if place.get_nearest_places %}
<div class="e-cat">
<div class="sect-title">{% trans 'Ближайшие выставочные центры' %}</div>
<ul class="cat-list cl-places">
{% for pl in place.get_nearest_places %}
<li class="cl-item">
<div class="cl-item-wrap clearfix">
<a href="{{ pl.get_permanent_url }}">
<div class="cli-pict">
{% include 'show_logo.html' with obj=pl %}
</div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title">
<a href="{{ pl.get_permanent_url }}"> {{ pl.name|safe }}</a>
</div>
<!--<div class="cli-rate">{{ pl.rating }}</div>-->
</header>
<div class="cli-descr">{{ pl.get_type }}</div>
</div>
<div class="cli-bot clearfix">
{% if pl.total_area %}
<div class="cli-dim">{{ pl.total_area }}</div>
{% endif %}
<div class="cli-place">
<a href="/places/country/{{ pl.country.url }}/">{{ pl.country }}</a>, <a href="places/city/{{ pl.city.url }}/">{{ pl.city }}</a>,
<a href="{{ pl.get_permanent_url }}">{{ pl.adress }}</a>
</div>
</div>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% include 'client/includes/banners/detail_inner_3.html' %}
</div>
<div class="cli-bot clearfix">
{% if pl.total_area %}
<div class="cli-dim">{{ pl.total_area }}</div>
{% endif %}
<div class="cli-place">
<a href="/places/country/{{ pl.country.url }}/">{{ pl.country }}</a>, <a href="places/city/{{ pl.city.url }}/">{{ pl.city }}</a>,
<a href="{{ pl.get_permanent_url }}">{{ pl.adress }}</a>
</div>
</div>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% include 'client/includes/banners/detail_inner_3.html' %}
</div>
{% endblock %}
{% block scripts %}

@ -0,0 +1,80 @@
{% load i18n %}
<div class="i-services">
<div class="sect-title">{% trans 'Услуги' %}</div>
<div class="is-wrap clearfix">
{% if place.place == 'place_exposition' %}
<ul>
{% if place.bank %}
<li>{% trans 'Банк / банкоматы / обмен валюты' %}</li>
{% endif %}
{% if place.wifi %}
<li>Wi-Fi</li>
{% endif %}
{% if place.children_room %}
<li>{% trans 'Детская комната' %}</li>
{% endif %}
{% if place.disabled_service %}
<li>{% trans 'Сервис для инвалидов' %}</li>
{% endif %}
</ul>
<ul>
{% if place.conference_centre %}
<li>{% trans 'Конгресс-центр' %}</li>
{% endif %}
{% if place.business_centre %}
<li>{% trans 'Бизнес-центр' %}</li>
{% endif %}
{% if place.online_registration %}
<li>{% trans 'Онлайн-регистрация' %}</li>
{% endif %}
{% if place.cafe %}
<li>{% trans 'Кафе и рестораны' %}</li>
{% endif %}
</ul>
<ul>
{% if place.terminals %}
<li>{% trans 'Информационные терминалы' %}</li>
{% endif %}
{% if place.parking %}
<li>{% trans 'Парковка' %}</li>
{% endif %}
{% if place.press_centre %}
<li>{% trans 'Пресс-центр' %}</li>
{% endif %}
{% if place.mobile_application %}
<li>{% trans 'Мобильное приложение' %}</li>
{% endif %}
</ul>
{% else %}
<ul>
{% if place.exposition_hall %}
<li>{% trans 'Выставочный зал' %}</li>
{% endif %}
{% if place.wifi %}
<li>Wi-Fi</li>
{% endif %}
{% if place.multimedia_equipment %}
<li>{% trans 'Мультимедийное оборудование' %}</li>
{% endif %}
{% if place.conference_call %}
<li>{% trans 'Конференц-связь' %}</li>
{% endif %}
</ul>
<ul>
{% if place.translate_equipment %}
<li>{% trans 'Оборудование для синхронного перевода' %}</li>
{% endif %}
{% if place.banquet_hall %}
<li>{% trans 'Банкетный зал' %}</li>
{% endif %}
{% if place.catering %}
<li>{% trans 'Кейтеринг' %}</li>
{% endif %}
{% if place.hotel %}
<li>{% trans 'Гостиница' %}</li>
{% endif %}
</ul>
{% endif %}
</div>
</div>
Loading…
Cancel
Save