Merge branch 'develop'

remotes/origin/HEAD
Slava Kyrachevsky 9 years ago
commit ffec26d7ba
  1. 1
      README.md
  2. 4
      apps/accounts/urls.py
  3. 48
      apps/accounts/views.py
  4. 2
      apps/conference/forms.py
  5. 33
      apps/emencia/django/newsletter/forms.py
  6. 38
      apps/emencia/django/newsletter/mailer.py
  7. 19
      apps/emencia/django/newsletter/management/commands/send_newsletter.py
  8. 6
      apps/emencia/django/newsletter/models.py
  9. 2
      apps/emencia/django/newsletter/urls/__init__.py
  10. 135
      apps/emencia/django/newsletter/views/expo_views.py
  11. 2
      apps/exposition/admin.py
  12. 2
      apps/exposition/forms.py
  13. 47
      apps/file/admin.py
  14. 41
      apps/file/forms.py
  15. 2
      apps/file/models.py
  16. 4
      apps/import_xls/excel_settings.py
  17. 64
      apps/import_xls/import_forms.py
  18. 48
      apps/import_xls/utils.py
  19. 2
      apps/place_exposition/forms.py
  20. 2
      proj/admin.py
  21. 26
      proj/settings.py
  22. 1
      requirements.txt
  23. 153
      static/custom_js/main.js
  24. 102
      static/custom_js/select_tag.js
  25. 89
      static/mailing_settings/css/main.css
  26. 59
      static/mailing_settings/js/main.js
  27. 192
      templates/c_admin/article/blog_form.html
  28. 34
      templates/c_admin/file/file_update.html
  29. 4
      templates/c_admin/newsletters/contact_list.html
  30. 2
      templates/c_admin/newsletters/newsletter_object.html
  31. 8
      templates/c_admin/place_exposition/place_exposition.html
  32. 215
      templates/client/newsletters/mailing_settings.html
  33. 603
      templates/client/service/participation.html

@ -13,7 +13,6 @@ INSTALLED_APPS += (
)
RAVEN_CONFIG = {
'dsn': 'http://474617c96350412d80735900c6717b9a:330285c9034947a181cbae8b52bb15d8@88.198.17.35:9000/3',
'release': raven.fetch_git_sha(os.path.dirname(os.pardir)),
}
```

@ -8,7 +8,6 @@ from views import (
CalendarView,
Feed,
HomeView,
MailingSettings,
NameView,
PhoneView,
ProfileCompanyView,
@ -21,7 +20,6 @@ from views import (
urlpatterns = patterns('',
url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())),
url(r'^profile/mailing/$', MailingSettings.as_view(), name='accounts-mailing_settings'),
url(r'^profile/settings/$', login_required(SettingsView.as_view()), name='accounts_settings'),
url(r'^profile/calendar/remove/$', 'accounts.views.remove_from_calendar'),
url(r'^profile/calendar/export/$', 'core.views.download_workbook'),
@ -44,7 +42,7 @@ urlpatterns = patterns('',
url(r'^profile/change-password/', 'accounts.views.change_password'),
url(
r'^profile/subscribe-themes-tags/$',
login_required(UserSubscribeThemesTagsView.as_view()),
UserSubscribeThemesTagsView.as_view(),
name='user_subscribe_themes_tags'
),

@ -27,7 +27,7 @@ from company.edit_forms import NameForm as CompNameForm, HomeForm as CompHomeFor
EmailForm as CompEmailForm, WebPageForm as CompWebPageForm, SocialForm as CompSocialForm,\
TagForm as CompTagForm, DescriptionForm as CompDescr, StaffForm as CompStaff, \
FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress
from emencia.django.newsletter.forms import SubscribeSettingsForm, MailingSettingsForm
from emencia.django.newsletter.forms import SubscribeSettingsForm
from emencia.django.newsletter.models import Contact, ContactSettings
from .forms import ChangePasswordForm, FeedFilterForm
@ -115,41 +115,6 @@ class GetUserMixin(object):
return instance
class MailingSettings(GetUserMixin, ContextMixin, AjaxableResponseMixin, CreateUpdateView):
form_class = MailingSettingsForm
template_name = 'client/newsletters/mailing_settings.html'
success_url = reverse_lazy('accounts-mailing_settings')
def get_success_url(self):
return self.success_url
def get_object(self):
self.extra_ctx.update({
'r_cities': City.used.russia(),
})
instance = self.get_user()
if instance is not None:
self.extra_ctx.update({
'checked_f_countries': list(instance.f_countries.values_list('pk', flat=True)),
'checked_r_cities': list(instance.r_cities.values_list('pk', flat=True)),
'checked_tg': list(instance.tags.values_list('pk', flat=True)),
'checked_th': list(instance.themes.values_list('pk', flat=True)),
'contact': instance,
})
if self.request.GET.get('unsibscribe') and instance.subscriber:
instance.unsubscribe()
self.extra_ctx.update({'unsubscribe_success': True})
elif not instance.subscriber:
self.extra_ctx.update({'unsubscribed': True})
return instance
def form_valid(self, form):
return super(MailingSettings, self).form_valid(form)
def form_invalid(self, form):
return super(MailingSettings, self).form_invalid(form)
class CalendarView(TemplateView):
"""
display template with user calendar(one month)
@ -578,11 +543,14 @@ class UserSubscribeThemesTagsView(GetUserMixin, TemplateView):
ctx = super(UserSubscribeThemesTagsView, self).get_context_data(**kwargs)
data = []
instance = self.get_user()
user_themes = []
user_tags = []
themes = Theme.objects.language().values('pk', 'name')
user_themes = instance.themes.values_list('pk', flat=True)
user_tags = instance.tags.values_list('pk', flat=True)
if instance is not None:
user_themes = instance.themes.values_list('pk', flat=True)
user_tags = instance.tags.values_list('pk', flat=True)
for theme in themes:
tags = []
@ -607,4 +575,6 @@ class UserSubscribeThemesTagsView(GetUserMixin, TemplateView):
def render_to_response(self, context, **response_kwargs):
context.pop('view')
return HttpResponse(json.dumps(context), content_type=self.content_type)
return HttpResponse(
json.dumps(context), content_type=self.content_type
)

@ -56,7 +56,7 @@ class ConferenceCreateForm(forms.Form):
#organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
# choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
org = forms.CharField(required=False, label=_(u'Организатор'))
country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.language().all()])
country = forms.ChoiceField(label=_(u'Страна'), choices=list(set([(c.id, c.name) for c in Country.objects.language().all()])))
theme = forms.MultipleChoiceField(label=_(u'Тематики'),
choices=[(item.id, item.name) for item in Theme.objects.language().all()])

@ -81,6 +81,12 @@ class MailingListSubscriptionForm(forms.ModelForm):
class MailingSettingsForm(forms.ModelForm):
email = forms.EmailField(
error_messages={
'required': _(u'Поле e-mail обязательно для заполнения')
},
widget=forms.TextInput(attrs={'placeholder': _(u'Ваш e-mail')})
)
r_cities = ML_ModelMultipleChoiceField(
label=_(u'Города России'), required=False,
queryset=City.objects.all())
@ -100,11 +106,12 @@ class MailingSettingsForm(forms.ModelForm):
class Meta:
model = Contact
fields = [
'moscow', 'russia', 'r_cities', 'foreign',
'email', 'first_name', 'moscow', 'russia', 'r_cities', 'foreign',
'periodic', 'periodic_day', 'content_news', 'content_overview',
'content_articles',
]
widgets = {
'first_name': forms.TextInput(attrs={'placeholder': _(u'Ваше имя')}),
'moscow': forms.CheckboxInput(),
'foreign': forms.CheckboxInput(),
'periodic': forms.RadioSelect(),
@ -119,6 +126,10 @@ class MailingSettingsForm(forms.ModelForm):
for field in ['co', 'r_cities', 'tg', 'th', 'area']:
self.fields[field].widget.attrs.update({'style': 'display: none;'})
if self.instance and self.instance.pk:
# если пользовать авторизован, у нас есть инстанс
# и там не нужно выводить для редактирования его личные данные
del self.fields['email']
del self.fields['first_name']
# area
self.initial['area'] = set(self.instance.area.values_list('pk', flat=True))
area_q = Area.objects.language().all().order_by('name')
@ -184,6 +195,19 @@ class MailingSettingsForm(forms.ModelForm):
obj.save()
return obj
def clean(self):
cleaned_data = super(MailingSettingsForm, self).clean()
if not cleaned_data.get('tg') and not cleaned_data.get('th'):
raise forms.ValidationError(_(u'Для успешной подписки необходимо '
u'выбрать тематики событий, которые '
u'вам интересны. На основе этих '
u'настроек мы включим в ваше письмо '
u'релевантные события!'))
if not cleaned_data.get('moscow') and not cleaned_data.get('russia') and not cleaned_data.get('foreign') and not cleaned_data.get('area') and not cleaned_data.get('r_cities') and not cleaned_data.get('co'):
raise forms.ValidationError(_(u'Необходимо выбрать минимум '
u'1 вариант в гео-фильтрах'))
return cleaned_data
class AllMailingListSubscriptionForm(MailingListSubscriptionForm):
"""Form for subscribing to all mailing list"""
@ -221,9 +245,10 @@ class ContactForm(forms.ModelForm):
def clean_email(self):
email = self.cleaned_data['email']
try:
self.instance = Contact.objects.get(email__iexact=email)
return email
except (Contact.DoesNotExist, ):
Contact.objects.get(email__iexact=email)
raise forms.ValidationError(_(u'Указанный e-mail адрес уже '
u'подписан на рассылку'))
except Contact.DoesNotExist:
pass
return email

@ -41,6 +41,7 @@ from django.template.loader import render_to_string, get_template
from django.utils.encoding import smart_str
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext as _
from django.utils import timezone
from django.core.files.storage import default_storage
from django.core.urlresolvers import reverse
from django.core.exceptions import SuspiciousOperation
@ -167,7 +168,13 @@ class NewsLetterSender(object):
all the attached files.
"""
content_html = self.build_email_content(contact, announce_context, name)
content_html = self.build_email_content(contact, announce_context)
if '{name}' in content_html:
content_html = content_html.format(
**{
'name': name or contact.first_name or contact.last_name or _(u'Подписчик')
}
)
h = HTMLParser.HTMLParser()
content_html = h.unescape(content_html)
@ -344,7 +351,6 @@ class NewsLetterSender(object):
logo_path = default_storage.path('newsletter/images/no-logo.png')
elif logo and not logo_path:
logo_path = logo.path
print(logo, logo_path, obj)
try:
ctype, encoding = mimetypes.guess_type(logo_path)
@ -392,7 +398,7 @@ class NewsLetterSender(object):
title = self.newsletter.title2.format(**self.preheader_ctx)
return title
def build_email_content(self, contact, announce_context=None, name=None):
def build_email_content(self, contact, announce_context=None):
"""Generate the mail for a contact"""
uidb36, token = tokenize(contact)
context = Context({'contact': contact,
@ -400,7 +406,6 @@ class NewsLetterSender(object):
'newsletter': self.newsletter,
'tracking_image_format': TRACKING_IMAGE_FORMAT,
'uidb36': uidb36, 'token': token,
'name': name or contact.first_name or contact.last_name or _(u'Подписчик'),
'settings_links': self.settings_links,
})
if self.announce:
@ -642,16 +647,18 @@ class Mailer(NewsLetterSender):
expedition_list = self.expedition_list
number_of_recipients = len(expedition_list)
if self.verbose:
print '%i emails will be sent' % number_of_recipients
# number_of_recipients = len(expedition_list)
# if self.verbose:
# print '%i emails will be sent' % number_of_recipients
i = 1
for contact in expedition_list:
# FIXME: Временно сделана отправка только 1 письма.
# См FIXME в команде send_newsletter
for i, contact in enumerate(expedition_list, 1):
print 'sending to contact: %s, %s (%s)' % (contact.pk, contact.email, timezone.now())
send = True
if self.verbose:
print '- Processing %s/%s (%s)' % (
i, number_of_recipients, contact.pk)
# if self.verbose:
# print '- Processing %s/%s (%s)' % (
# i, number_of_recipients, contact.pk)
#
self.build_preheader_ctx(contact)
@ -693,8 +700,6 @@ class Mailer(NewsLetterSender):
self.smtp.quit()
self.smtp_connect()
i += 1
# маркируем оставшиеся контакты на второй этап
self.mark_contacts_for_second_stage()
@ -716,10 +721,13 @@ class Mailer(NewsLetterSender):
return []
if self.newsletter.dailymail and not self.test:
return self.newsletter.get_dailymail_subscribers()
# FIXME: врменно добавил жёсткий срез для отправки 1 письма
return self.newsletter.get_dailymail_subscribers()[:1]
qs = super(Mailer, self).expedition_list
# FIXME: врменно добавил жёсткий срез для отправки 1 письма
self.credits = 1
qs = qs[:self.credits]
if self.test:

@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
"""Command for sending the newsletter"""
from datetime import datetime, timedelta
from time import sleep
from django.conf import settings
from django.utils.translation import activate
from django.utils import timezone
from django.core.management.base import NoArgsCommand
from emencia.django.newsletter.settings import SEND_HOUR_LOOP
@ -20,14 +22,17 @@ class Command(NoArgsCommand):
self.verbose = int(options['verbosity'])
activate(settings.LANGUAGE_CODE)
if SEND_HOUR_LOOP:
while self.end_time > datetime.now():
self.send()
sleep(30)
else:
self.send()
# FIXME: временно делаем одну отправку и завершаем.
# Это сделано для того, чтобы отправка писем была более контролируемая
self.send()
# if SEND_HOUR_LOOP:
# while self.end_time > datetime.now():
# self.send()
# sleep(30)
# else:
# self.send()
if self.verbose:
print 'End session sending'
print 'End session sending (%s)' % timezone.now()
def send(self):
for newsletter in Newsletter.objects.exclude(

@ -157,10 +157,10 @@ class Contact(models.Model):
from_users = models.BooleanField(default=False)
dailymailing = models.BooleanField(default=False)
moscow = models.BooleanField(_(u'Москва'), blank=True, default=True)
russia = models.BooleanField(_(u'Россия'), blank=True, default=True)
moscow = models.BooleanField(_(u'Москва'), blank=True, default=False)
russia = models.BooleanField(_(u'Россия'), blank=True, default=False)
r_cities = models.ManyToManyField('city.City', blank=True, null=True, verbose_name=_(u'Города России'))
foreign = models.BooleanField(_(u'Зарубеж'), blank=True, default=True)
foreign = models.BooleanField(_(u'Зарубеж'), blank=True, default=False)
f_countries = models.ManyToManyField('country.Country', blank=True, null=True, verbose_name=_(u'Зарубежные страны'))
area = models.ManyToManyField('country.Area', blank=True, null=True, verbose_name=_(u'Географическая зона'))
periodic = models.PositiveSmallIntegerField(_(u'Периодичность отправки'),

@ -12,7 +12,7 @@ urlpatterns = patterns('',
url(r'^statistics/', include('emencia.django.newsletter.urls.statistics')),
url(r'^', include('emencia.django.newsletter.urls.newsletter')),
url(r'^test-letter/', TemplateView.as_view(template_name='client/newsletters/announce_template.html')),
url(r'^test-letter/', TemplateView.as_view(template_name='client/newsletters/announce_template.html'), name='newsletter_test_letter'),
url(r'^activation/send/', TemplateView.as_view(template_name='client/newsletters/activation_send.html'),
name='subscription_activation_send'),
url(r'^activation/complete/', TemplateView.as_view(template_name='client/newsletters/activation_complete.html'),

@ -3,7 +3,7 @@ import json
from django.core.urlresolvers import reverse_lazy
from django.views.generic import TemplateView, FormView
from django.http import HttpResponseRedirect, HttpResponse
from django.http import HttpResponse
from django.shortcuts import redirect
from emencia.django.newsletter.forms import ContactForm
@ -13,82 +13,97 @@ from emencia.django.newsletter.forms import (
)
from accounts.models import User
from accounts.views import GetUserMixin
from functions.custom_views import ContextMixin
from functions.http import JsonResponse
from city.models import City
class SubscribeView(GetUserMixin, ContextMixin, FormView):
form_class = ContactForm
class SubscribeView(GetUserMixin, FormView):
"""
Представление для подписки не/авторизованных пользователей
"""
template_name = 'client/newsletters/mailing_settings.html'
success_url = reverse_lazy('subscription_activation_send')
def get_form(self, form_class):
if self.request.POST:
email = self.request.POST.get('email')
if email:
try:
contact = Contact.objects.get(email=email)
return form_class(instance=contact,
**self.get_form_kwargs())
except Contact.DoesNotExist:
pass
return form_class(**self.get_form_kwargs())
else:
return form_class(**self.get_form_kwargs())
form_class = MailingSettingsForm
def get_object(self):
return self.get_user()
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(SubscribeView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(SubscribeView, self).post(request, *args, **kwargs)
def form_valid(self, form):
contact = form.save()
contact.send_activation()
return HttpResponseRedirect(self.success_url)
if self.request.POST.get('save'):
contact = form.save()
if not self.request.user.is_authenticated():
contact.send_activation()
if self.request.is_ajax():
data = {'success': True}
if self.request.POST.get('save'):
data['redirect_url'] = str(self.get_success_url())
return JsonResponse(data)
return redirect(self.get_success_url())
def form_invalid(self, form):
if self.request.is_ajax():
data = {
'form_errors': form.errors,
}
return JsonResponse(data, status=400)
return self.render_to_response(self.get_context_data(form=form))
def get_initial(self):
data = super(SubscribeView, self).get_initial()
if self.request.user.is_authenticated():
email = getattr(self.request.user, 'email')
data['email'] = email
data['first_name'] = getattr(self.request.user, 'first_name')
if self.request.GET:
if self.request.GET.get('email'):
data['email'] = self.request.GET['email']
if self.request.GET.get('first_name'):
data['first_name'] = self.request.GET['first_name']
if self.request.GET.get('email'):
data['email'] = self.request.GET['email']
if self.request.GET.get('first_name'):
data['first_name'] = self.request.GET['first_name']
return data
def get_form_kwargs(self):
kwargs = super(SubscribeView, self).get_form_kwargs()
if self.request.user.is_authenticated():
kwargs.update({'instance': self.object})
return kwargs
def get_success_url(self):
if not self.request.user.is_authenticated():
return reverse_lazy('subscription_activation_send')
return reverse_lazy('newsletter_subscription')
def get_context_data(self, **kwargs):
ctx = super(SubscribeView, self).get_context_data(**kwargs)
ctx['object'] = self.get_mailsettings_object()
ctx['mailsettings_form'] = MailingSettingsForm(
instance=self.get_user()
)
ctx['object'] = self.object
ctx['r_cities'] = self.get_russian_cities()
ctx['checked_th'] = self.get_checked_th()
if self.object is not None:
if self.request.GET.get('unsibscribe') and self.object.subscriber:
self.object.unsubscribe()
ctx['unsubscribe_success'] = True
elif not self.object.subscriber:
ctx['unsubscribed'] = True
return ctx
def get_mailsettings_object(self):
def get_russian_cities(self):
"""
:return: города России
"""
return City.used.russia()
def get_checked_th(self):
"""
передаём контекст в шаблон по городам, странам, а так же выбранным
:return: instance of mail settings
:return: выбранные пользователем темы
"""
self.extra_ctx.update({
'r_cities': City.used.russia(),
})
instance = self.get_user()
if instance is not None:
self.extra_ctx.update({
'checked_f_countries': list(
instance.f_countries.values_list('pk', flat=True)),
'checked_r_cities': list(
instance.r_cities.values_list('pk', flat=True)),
'checked_tg': list(instance.tags.values_list('pk', flat=True)),
'checked_th': list(
instance.themes.values_list('pk', flat=True)),
'contact': instance,
})
if self.request.GET.get('unsibscribe') and instance.subscriber:
instance.unsubscribe()
self.extra_ctx.update({'unsubscribe_success': True})
elif not instance.subscriber:
self.extra_ctx.update({'unsubscribed': True})
return instance
if self.object is not None:
return self.object.themes.values_list('pk', flat=True)
return []
class ActivationView(TemplateView):

@ -278,7 +278,7 @@ class ExpositionView(AdminView):
'expohit': obj.expohit, 'discount': obj.discount,
'canceled': obj.canceled, 'moved': obj.moved, 'logo': obj.logo,
'visitors': obj.visitors, 'members': obj.members,
'audience':[item for item, bool in obj.audience.all() if bool],
'audience': [item for item in obj.audience.all()],
'quality_label': [item for item, bool in obj.quality_label if bool],
'place_alt': obj.place_alt}

@ -49,7 +49,7 @@ class ExpositionCreateForm(forms.Form):
#company = forms.MultipleChoiceField(label=u'Компании', required=False,
# choices=[(item.id, item.name) for item in Company.objects.language().all()] )
country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.language().all()])
country = forms.ChoiceField(label=_(u'Страна'), choices=list(set([(c.id, c.name) for c in Country.objects.language().all()])))
theme = forms.MultipleChoiceField(
label=_(u'Тематики'),
choices=[(item.id, item.name) for item in Theme.objects.language().filter(types=Theme.types.exposition)])

@ -4,12 +4,15 @@ from django.views.decorators.csrf import csrf_exempt
from django.db.models.loading import get_model
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponse
from django.views.generic import UpdateView
from django.views.generic import FormView
from django.shortcuts import get_object_or_404
from django.conf import settings
from .models import FileModel
from .forms import FileForm, FileUpdateForm
import json
import magic
@csrf_exempt
@ -27,8 +30,15 @@ def ajax_post_file(request, obj_id):
if request.is_ajax() and request.method == 'POST':
file_form = FileForm(request.POST, request.FILES)
if file_form.is_valid():
file_form.save(request.FILES, obj)
f = file_form.save(request.FILES, obj)
mime = magic.Magic(mime=True)
data['success'] = True
data['name'] = f.file_name or f.file_path.name
data['size'] = f.file_path.size
data['file'] = f.file_path.url
data['type'] = mime.from_file(f.file_path.path)
data['remove_url'] = reverse('ajax_delete_file', args=[f.pk])
data['detail_link'] = reverse('file_update', args=[f.pk])
else:
data['errors'] = file_form.errors
@ -39,11 +49,12 @@ def ajax_post_file(request, obj_id):
)
files_data = []
for f in files:
mime = magic.Magic(mime=True)
files_data.append({
'name': f.file_name or f.file_path.name,
'size': f.file_path.size,
'file': f.file_path.url,
'type': 'file',
'type': mime.from_file(f.file_path.path),
'remove_url': reverse('ajax_delete_file', args=[f.pk]),
'detail_link': reverse('file_update', args=[f.pk])
})
@ -66,10 +77,36 @@ def ajax_delete_file(request, id):
return HttpResponse(json.dumps(data), content_type='application/json')
class FileUpdateView(UpdateView):
class FileUpdateView(FormView):
"""
Представление обновления файла
"""
template_name = 'c_admin/file/file_update.html'
form_class = FileUpdateForm
model = FileModel
def get_object(self):
pk = self.kwargs.get('pk')
return get_object_or_404(FileModel, pk=pk)
def get_initial(self):
data = super(FileUpdateView, self).get_initial()
obj = self.get_object()
data['file_path'] = obj.file_path
data['purpose'] = obj.purpose
for lid, (code, name) in enumerate(settings.LANGUAGES):
data['file_name_%s' % code] = obj.file_name.translate(code)
data['description_%s' % code] = obj.description.translate(code)
return data
def form_valid(self, form):
form.save(self.request, self.kwargs.get('pk'))
return super(FileUpdateView, self).form_valid(form)
def get_success_url(self):
return reverse('file_update', args=[self.get_object().pk])
def get_context_data(self, **kwargs):
ctx = super(FileUpdateView, self).get_context_data(**kwargs)
ctx['object'] = self.get_object()
ctx['languages'] = settings.LANGUAGES
return ctx

@ -84,13 +84,46 @@ class FileForm(forms.Form):
return file_obj
class FileUpdateForm(forms.ModelForm):
class FileUpdateForm(forms.Form):
"""
Форма обновления файла в админ панели
"""
class Meta:
model = FileModel
fields = ('file_path',)
file_path = forms.FileField(label=_(u'Выберите файл'))
purpose = forms.ChoiceField(label=_(u'Назаначение'), choices=PURPOSES)
def __init__(self, *args, **kwargs):
"""
Создаём динамические поля переводов
"""
super(FileUpdateForm, self).__init__(*args, **kwargs)
for lid, (code, name) in enumerate(settings.LANGUAGES):
self.fields['file_name_%s' % code] = forms.CharField(
label=_(u'Имя файла'),
required=False,
widget=forms.TextInput(attrs={'placeholder': 'Имя'})
)
self.fields['description_%s' % code] = forms.CharField(
label=_(u'Описание'),
required=False,
widget=CKEditorWidget()
)
def save(self, request, id=None):
data = self.cleaned_data
if id is None:
f = FileModel()
else:
f = FileModel.objects.get(id=id)
f.file_path = data['file_path']
f.purpose = data['purpose']
f.save()
# fill translated fields and save object
fill_trans_fields_all(FileModel, f, data, id=id)
return f
class FileModelForm(forms.Form):

@ -22,7 +22,7 @@ PURPOSES = (
('scheme teritory', _(u'Схема територии')),
('diplom', _(u'Дипломы')),
('preview', _(u'Превью')),
('preview2', _(u'Превью')),
('preview2', _(u'Превью 2')),
)

@ -284,7 +284,7 @@ event_sett = {
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'audience', u'func': to_audience, u'method': True},
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},
@ -511,4 +511,4 @@ import_settings={
'is_published': {'func': bool},
'canceled_by_administrator': {'func': bool},
'types': {'func': to_theme_type}
}
}

@ -420,7 +420,6 @@ class ImportEventForm(ImportForm):
if setting is None:
continue
if setting.get('method'):
# this cell contains data that must be written after creating object
if cell != "":
@ -549,40 +548,39 @@ class ImportEventForm(ImportForm):
list_dicts.append(d)
"""
# go through row cells
# field name current cell
field_name = field_names[col_number]
if field_name =='theme':
# need save object before saving manytomany field
#object.save()
setting = import_settings.get(field_name)
d[setting] = cell
"""
# go through row cells
# field name current cell
field_name = field_names[col_number]
if field_name =='theme':
# need save object before saving manytomany field
#object.save()
setting = import_settings.get(field_name)
d[setting] = cell
if setting is not None:
# if setting exist for this field
func = setting.get('func')
if func is not None:
extra_value = setting.get('extra_values')
if extra_value is not None:
# if setting has extra value then
# it is some field like city, theme, 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)
if cell:
value = func(cell, lang, getattr(object, extra_value))
else:
value = None
else:
value = func(cell)
if value:
setattr(object, field_name, value)
"""
if setting is not None:
# if setting exist for this field
func = setting.get('func')
if func is not None:
extra_value = setting.get('extra_values')
if extra_value is not None:
# if setting has extra value then
# it is some field like city, theme, 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)
if cell:
value = func(cell, lang, getattr(object, extra_value))
else:
value = None
else:
value = func(cell)
if value:
setattr(object, field_name, value)
"""
#object.save()
#object.save()

@ -6,9 +6,8 @@ from PIL import Image
from django.conf import settings
from django.utils import translation
from hvad.utils import get_translation_aware_manager
from bitfield import BitHandler
from place_exposition.models import PlaceExposition
from exposition.models import Exposition
from events.models import TargetAudience
from country.models import Country
from city.models import City
from theme.models import Theme, Tag
@ -134,32 +133,29 @@ def to_periodic(value):
return periodic.get(value, 0)
def to_audience(value, model=Exposition):
if value:
translation.activate('ru')
l = value.split(', ')
if l:
new_list = []
for value in l:
for item1, item2 in BIT_AUDIENCE:
if value == item2:
new_list.append(item1)
if new_list:
return reduce(lambda x,y: x|y, (getattr(model.audience, item) for item in new_list))
return 0
def to_audience(obj, value):
# new_list = []
# if value:
# translation.activate('ru')
# l = value.split(', ')
# target_audience = TargetAudience.objects.all()
# print l
# for value in l:
# for ta in target_audience:
# if value == ta.title:
# new_list.append(ta.pk)
# return new_list
translation.activate('ru')
target_audience = TargetAudience.objects.filter(title__in=value.split(', ')).values_list('pk', flat=True)
obj.audience.clear()
obj.audience.add(*TargetAudience.objects.filter(id__in=target_audience))
return None
def get_audience(value):
if isinstance(value, BitHandler):
l = [k for k, v in value.iteritems() if v]
if l:
new_list = []
for value in l:
for item1, item2 in BIT_AUDIENCE:
if value == item1:
new_list.append(unicode(item2))
return ', '.join(new_list)
return ''
new_list = [x.title for x in value.all()]
return ', '.join(new_list)
import types
def save_logo(obj, path):

@ -30,7 +30,7 @@ class ExpositionForm(forms.Form):
type = forms.ChoiceField(required=False, choices=types)
logo = forms.ImageField(label=_(u'Logo'), required=False, max_length=500)
country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.language().all()])
country = forms.ChoiceField(label=_(u'Страна'), choices=list(set([(c.id, c.name) for c in Country.objects.language().all()])))
# creates select input with empty choices cause it will be filled with ajax
city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput())

@ -26,7 +26,7 @@ def ajax_city(request):
returns html <option> tags filled with cities filtered by country value from request
"""
objects = City.objects.language().filter(country=request.GET['id']).order_by('name')
return render_to_response('select.html', {'objects': objects})
return render_to_response('c_admin/select.html', {'objects': objects})
def ajax_tag(request):

@ -416,7 +416,9 @@ CRONJOBS = [
('40 6 * * * ', 'django.core.management.call_command', ['newsletter_contacts_remove_notactivated']),
('30 2 * * *', 'django.core.management.call_command', ['newsletter_create_dailymail']),
('35 * * * *', 'django.core.management.call_command', ['send_newsletter']),
# FIXME: команда временно переделана на отправку 1 письма.
# В свою очередь запуск по крону будет происходить допустим каждые 2 секунды
# ('35 * * * *', 'django.core.management.call_command', ['send_newsletter']),
('12 4 * * *', 'django.core.management.call_command', ['stats_daily']),
('5 10 * * *', 'django.core.management.call_command', ['update_events_filter_fields']),
@ -434,28 +436,6 @@ HAYSTACK_CONNECTIONS = {
},
}
# TODO automate crons
"""
# update search indexes
0 * * * * /usr/bin/python /var/www/proj/manage.py update_index conference --remove --age=6
0 * * * * /usr/bin/python /var/www/proj/manage.py update_index exposition --remove --age=6
0 1,13 * * * /usr/bin/python /var/www/proj/manage.py update_index place_exposition --remove --age=24
0 3 * * * /usr/bin/python /var/www/proj/manage.py update_index company --remove --age=48
0 4 * * * /usr/bin/python /var/www/proj/manage.py update_index theme --remove --age=48
0 5 * * * /usr/bin/python /var/www/proj/manage.py update_index tag --remove --age=48
0 6 * * * /usr/bin/python /var/www/proj/manage.py update_index country --remove --age=48
0 7 * * * /usr/bin/python /var/www/proj/manage.py update_index city --remove --age=48
# update banner logs
10 * * * * /usr/bin/python /var/www/proj/manage.py banner_log_update
20 2,14 * * * /usr/bin/python /var/www/proj/manage.py banner_log_check_previous_day
# update hotels prices
20 1 * * 6 /usr/bin/python /var/www/proj/manage.py update_hotels_price
# newsletter
20 * * * * /usr/bin/python /var/www/proj/manage.py send_newsletter
40 6 * * * /usr/bin/python /var/www/proj/manage.py newsletter_contacts_remove_notactivated
"""
THUMBNAIL_ENGINE = "proj.sorlengine.SorlEngine"
THUMBNAIL_FORMAT = "PNG"

@ -44,6 +44,7 @@ pymorphy2==0.8
pymorphy2-dicts==2.4.393442.3710985
pysolr==3.2.0
python-dateutil==2.2
python-magic==0.4.12
python-memcached==1.48
python-openid==2.2.5
python-social-auth==0.1.23

@ -224,18 +224,17 @@ $(document).ready(function(){
$('.off').click(function(){
var url = $(this).attr('href')
var $this = $(this)
$.get(
url, function(data){
if (data == 'off'){
$this.hide();
$this.siblings('.on').show();
}
}
)
$.get(url,function(data){
if (data == 'off'){
$this.hide();
$this.siblings('.on').show();
}
});
return false;
});
// end on-of events
if( $("#id_city" ).length ) {
if( $("#id_city").length ) {
$('#id_city').select2({
placeholder: "Город",
width: 'element',
@ -245,7 +244,7 @@ $(document).ready(function(){
dataType: "json",
quietMillis: 200,
data: function(term, page, country){
data: function(term, page){
var country = $('#id_country').val();
return {term: term,
page: page,
@ -253,21 +252,23 @@ $(document).ready(function(){
},
results: function (data) {
console.log('results');
if (typeof(data) == 'string'){
data = JSON.parse(data);
}
console.log(data);
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.label
id: item.id,
text: item.label
});
});
return {results: results};
}
},
initSelection : function(element, callback) {
var id= $(element).val();
var id = $(element).val();
var text = $(element).attr('data-init-text');
callback({id: id, text:text});
}
@ -325,13 +326,12 @@ $(document).ready(function(){
}
if( $("#id_tag" ).length && $("#id_tag").is('select')) {
try{
$('#id_tag').select2({
placeholder: "Теги",
width: '550px',
multiple: true,
ajax: {
placeholder: "Теги",
width: '550px',
multiple: true,
ajax: {
url: "/admin/theme/tag/search/",
dataType: "json",
quietMillis: 200,
@ -339,9 +339,11 @@ $(document).ready(function(){
data: function(term, page, theme){
var theme = $('#id_theme').serialize();
return {term: term,
page: page,
theme: theme};
return {
term: term,
page: page,
theme: theme
};
},
results: function (data) {
@ -365,10 +367,12 @@ $(document).ready(function(){
});
});
callback(data);
}
});
} catch (e) {
console.log('===== Error =====');
console.warn(e);
console.log('=================')
}
@ -377,52 +381,55 @@ $(document).ready(function(){
*/
// theme change
$('#id_theme').change(function(){
$.get(
"/admin/ajax_tag/", {'id': $(this).serialize()}, function(data){
var optionValues = [];
var getValues = [];
var selectedValues = []
//push values sended from server in array
$.each(data, function(i, elem){
getValues.push(elem[0].toString())
});
//delete options if they aren't in getvalues
//otherwise push it in array
//also push in array already selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this), getValues);
if ($(this).is(':selected') ){
selectedValues.push($(this).val())
}
if (check == -1){
$(this).remove()
}
else{
optionValues.push($(this).val());
}
});
//generate new options
//old options unchanged
var html = ''
$.each(data, function(i, elem){
var check = $.inArray(elem[0].toString(), optionValues);
if (check == -1){
html += '<option value="';
html += elem[0];
html += '">';
html += elem[1];
html += '</option>';
}
});
$('#id_tag').append(html);
//select previous selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this).val(), selectedValues)
if (check != -1){
$(this).attr('selected', 'selected');
}
});
$.get("/admin/ajax_tag/", {'id': $(this).serialize()}, function(data){
var optionValues = [];
var getValues = [];
var selectedValues = [];
//push values sended from server in array
$.each(data, function(i, elem){
getValues.push(elem[0].toString())
});
//delete options if they aren't in getvalues
//otherwise push it in array
//also push in array already selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this), getValues);
if ($(this).is(':selected') ){
selectedValues.push($(this).val())
}
if (check == -1){
$(this).remove()
}
else{
optionValues.push($(this).val());
}
});
//generate new options
//old options unchanged
var html = ''
$.each(data, function(i, elem){
var check = $.inArray(elem[0].toString(), optionValues);
if (check == -1){
html += '<option value="';
html += elem[0];
html += '">';
html += elem[1];
html += '</option>';
}
});
$('#id_tag').append(html);
//select previous selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this).val(), selectedValues)
if (check != -1){
$(this).attr('selected', 'selected');
}
});
});//end get
});//end change
@ -499,7 +506,11 @@ $(document).ready(function(){
allowClear: true
});
} catch (e){}
} catch (e){
console.log('===== Error =====');
console.warn(e);
console.log('=================');
}
}

@ -1,52 +1,56 @@
// replace
$(document).ready(function(){
$('#id_theme').change(function(){
$.get(
"/admin/ajax_tag/", {'id': $(this).serialize()}, function(data){
var optionValues = [];
var getValues = [];
var selectedValues = []
//push values sended from server in array
$.each(data, function(i, elem){
getValues.push(elem[0].toString())
});
//delete options if they aren't in getvalues
//otherwise push it in array
//also push in array already selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this), getValues);
if ($(this).is(':selected') ){
selectedValues.push($(this).val())
}
if (check == -1){
$(this).remove()
}
else{
optionValues.push($(this).val());
}
});
//generate new options
//old options unchanged
var html = ''
$.each(data, function(i, elem){
var check = $.inArray(elem[0].toString(), optionValues);
$('#id_theme').change(function(){
$.get("/admin/ajax_tag/", {'id': $(this).serialize()}, function(data){
var optionValues = [];
var getValues = [];
var selectedValues = [];
if (check == -1){
html += '<option value="';
html += elem[0];
html += '">';
html += elem[1];
html += '</option>';
}
});
$('#id_tag').append(html);
//select previous selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this).val(), selectedValues)
if (check != -1){
$(this).attr('selected', 'selected');
}
});
});//end get
});//end change
});//end ready
//push values sended from server in array
$.each(data, function(i, elem){
getValues.push(elem[0].toString())
});
//delete options if they aren't in getvalues
//otherwise push it in array
//also push in array already selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this), getValues);
if ($(this).is(':selected') ){
selectedValues.push($(this).val())
}
if (check == -1){
$(this).remove()
}
else{
optionValues.push($(this).val());
}
});
//generate new options
//old options unchanged
var html = '';
$.each(data, function(i, elem){
var check = $.inArray(elem[0].toString(), optionValues);
if (check == -1){
html += '<option value="';
html += elem[0];
html += '">';
html += elem[1];
html += '</option>';
}
});
$('#id_tag').append(html);
//select previous selected values
$('#id_tag option').each(function() {
var check = $.inArray($(this).val(), selectedValues)
if (check != -1){
$(this).attr('selected', 'selected');
}
});
});//end get
});//end change
});//end ready

@ -842,35 +842,84 @@ a.themes_trigger{
}
.pr-form .pr-row{
overflow:hidden;
/*overflow:hidden;*/
margin:0 0 14px;
}
.pr-form .pr-row:after{
content: '';
display: block;
clear: both;
}
.pr-input{
float:left;
display: inline-block;
vertical-align: bottom;
margin:0 0 0 13px;
}
.errorlist{
list-style: none;
}
.text_error{
display: block;
text-align: center;
font-weight: 300;
font-size: 14px;
color: #bd2626;
padding-bottom: 3px;
}
.pr-input input.field_error{
box-shadow: 0 0 0 2px #f00;
}
.pr-input:first-child{
margin:0;
}
.pr-input.pr-name input{
background:#fff url(../images/pr-icon02.png) no-repeat 210px 50%;
}
.pr-input.pr-email input{
background:#fff url(../images/pr-icon03.png) no-repeat 210px 50%;
}
.pr-form input {
border:none;
color:#000;
font:17px/21px 'pf_dindisplay_promedium', Arial, Helvetica, sans-serif;
height:46px;
width:186px;
width:247px;
padding:0 44px 0 18px;
margin:0 0 0 13px;
background:#fff;
border-radius:4px;
position:relative;
}
.pr-input:first-child{
margin:0;
.pr-form input:focus::-webkit-input-placeholder {
color:transparent;
}
.pr-form input:focus:-moz-placeholder {
color:transparent;
}
.pr-form input:focus:-ms-input-placeholder {
color:transparent;
}
.pr-form input:focus::-moz-placeholder {
color:transparent;
}
.pr-input:after{
content:'';
position:absolute;
top:13px;
right:14px;
width:20px;
height:20px;
.pr-form input::-webkit-input-placeholder { /* WebKit browsers */
color:#808080;
opacity:1;
}
.pr-input.pr-name:after{
background:url(../images/pr-icon02.png) no-repeat 50% 50%;
.pr-form input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color:#808080;
opacity:1;
}
.pr-input.pr-email:after{
background:url(../images/pr-icon03.png) no-repeat 50% 50%;
.pr-form input::-moz-placeholder { /* Mozilla Firefox 19+ */
color:#808080;
opacity:1;
}
.pr-form input:-ms-input-placeholder { /* Internet Explorer 10+ */
color:#808080;
opacity:1;
}
.pr-form button{
@ -890,4 +939,8 @@ a.themes_trigger{
-ms-transition: all 100ms linear;
-o-transition: all 100ms linear;
transition: all 100ms linear;
}
}
.error_messages .errorlist{
list-style: decimal inside;
}

@ -1,13 +1,52 @@
'use strict';
function sendForm () {
var $form = $('#mailing_settings_form');
function sendForm (show_modal) {
var show_modal = show_modal || false,
$form = $('#mailing_settings_form');
$form.find('.field_error').removeClass('field_error');
$form.find('.text_error').remove();
var form_data = $form.serializeArray();
if (show_modal) {
form_data.push({
name: 'save',
value: true
})
}
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: $form.serializeArray(),
data: form_data,
success: function(response){
console.log(response);
if (response.hasOwnProperty('redirect_url')){
window.location.pathname = response.redirect_url;
}
},
error: function (error) {
var form_errors = error.responseJSON.form_errors;
if (show_modal){
var $error_list = $('<ol></ol>', {class: 'errorlist'});
$.each(form_errors, function (field, err) {
$error_list.append('<li>' + err + '</li>');
});
$('#error_messages').html($error_list);
$.fancybox.open({
href: '#error_modal'
})
} else {
$.each(form_errors, function (field, err) {
var $field = $form.find('#id_' + field);
$field.addClass('field_error');
$field.parent('.pr-input').prepend('<span class="text_error">' + err + '</span>');
});
}
}
});
}
@ -123,7 +162,6 @@ function sendForm () {
});
}
function isAllTagsChecked (theme_id) {
return themes_data[theme_id].tags.every(function (obj) {
return obj.checked;
@ -361,6 +399,13 @@ function sendForm () {
$themes_modal.on('click', '.modal-approve', function () {
var $selected = $selected_themes.find('li').removeClass('unsaved').clone();
if ($('#pr-promo').length){
if (!$('#id_moscow').is(':checked') && !$('#id_russia').is(':checked') && $selected_themes.children().length && !$('#selected_themes').children().length){
$('#id_moscow').prop('checked', true);
$('#id_russia').prop('checked', true);
}
}
$('#selected_themes').html($selected);
sendForm();
@ -371,6 +416,12 @@ function sendForm () {
$selected_themes.find('a').trigger('click');
});
$('#mailing_settings_form button').on('click', function (event) {
event.preventDefault();
var show_modal = true;
sendForm(show_modal);
});
})();

@ -15,17 +15,17 @@
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script>
$(document).ready(function(){
$('#id_publish_date').datetimepicker({
<script>
$(document).ready(function(){
$('#id_publish_date').datetimepicker({
todayHighlight: true,
format : 'yyyy-mm-dd',
minView:2
});
});
});
</script>
</script>
<link rel="stylesheet" href="{% static 'jQuery-filer/css/jquery.filer.css' %}">
<link rel="stylesheet" href="{% static 'jQuery-filer/css/jquery.filer-dragdropbox-theme.css' %}">
<script src="{% static 'jQuery-filer/js/jquery.filer.js' %}"></script>
@ -43,6 +43,7 @@
<div class="box-header well">
<h2><i class="icon-pencil"></i> {% trans "Основная информация" %}</h2>
</div>
<div class="box-content">
{# main_title #}
@ -50,35 +51,38 @@
<div class="control-group {% if form.publish_date.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.publish_date.label }}:</b></label>
<div class="controls">
{{ form.publish_date }}
<span class="help-inline">{{ form.publish_date.errors }}</span>
</div>
<div class="controls">
{{ form.publish_date }}
<span class="help-inline">{{ form.publish_date.errors }}</span>
</div>
</div>
{% if not article %}
<div class="control-group {% if form.slug.errors %}error{% endif %}">
<label class="control-label">{{ form.slug.label }}:</label>
<div class="control-group {% if form.slug.errors %}error{% endif %}">
<label class="control-label">{{ form.slug.label }}:</label>
<div class="controls">
{{ form.slug }}
<span class="help-inline">{{ form.slug.errors }}</span>
</div>
</div>
</div>
{% endif %}
{# theme #}
<div class="control-group {% if form.theme.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.theme.label }}:</b></label>
<div class="controls">
{{ form.theme }}
<span class="help-inline">{{ form.theme.errors }}</span>
</div>
<div class="controls">
{{ form.theme }}
<span class="help-inline">{{ form.theme.errors }}</span>
</div>
</div>
{# tag #}
<div class="control-group {% if form.tag.errors %}error{% endif %}">
<label class="control-label">{{ form.tag.label }}:</label>
<div class="controls">
{{ form.tag }}
<span class="help-inline">{{ form.tag.errors }}</span>
</div>
<div class="controls">
{{ form.tag }}
<span class="help-inline">{{ form.tag.errors }}</span>
</div>
</div>
{# exposition #}
{% if form.exposition %}
@ -160,78 +164,78 @@
{% block bot_scripts %}
<script>
$(document).ready(function(){
$('#id_exposition').select2({
placeholder: "Выставка",
multiple: false,
width: 'element',
ajax: {
url: "/admin/exposition/search/",
width: '550px',
dataType: "json",
quietMillis: 200,
data: function(term, page, theme){
return {term: term,
page: page};
},
results: function (data) {
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.label
});
});
return {results: results};
}
},
initSelection : function(element, callback) {
var id= $(element).val();
var text = $(element).attr('data-init-text');
callback({id: id, text:text});
}
});
$('#id_conference').select2({
placeholder: "Конференция",
multiple: false,
width: 'element',
ajax: {
url: "/admin/conference/search/",
width: '550px',
dataType: "json",
quietMillis: 200,
data: function(term, page, theme){
return {term: term,
page: page};
},
results: function (data) {
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.label
});
});
return {results: results};
}
},
initSelection : function(element, callback) {
var id= $(element).val();
var text = $(element).attr('data-init-text');
callback({id: id, text:text});
}
});
});
</script>
<script>
$(document).ready(function(){
$('#id_exposition').select2({
placeholder: "Выставка",
multiple: false,
width: 'element',
ajax: {
url: "/admin/exposition/search/",
width: '550px',
dataType: "json",
quietMillis: 200,
data: function(term, page, theme){
return {term: term,
page: page};
},
results: function (data) {
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.label
});
});
return {results: results};
}
},
initSelection : function(element, callback) {
var id= $(element).val();
var text = $(element).attr('data-init-text');
callback({id: id, text:text});
}
});
$('#id_conference').select2({
placeholder: "Конференция",
multiple: false,
width: 'element',
ajax: {
url: "/admin/conference/search/",
width: '550px',
dataType: "json",
quietMillis: 200,
data: function(term, page, theme){
return {term: term,
page: page};
},
results: function (data) {
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.label
});
});
return {results: results};
}
},
initSelection : function(element, callback) {
var id= $(element).val();
var text = $(element).attr('data-init-text');
callback({id: id, text:text});
}
});
});
</script>
{% endblock %}

@ -1,7 +1,13 @@
{% extends 'c_admin/base.html' %}
{% load static %}
{% block scripts %}
<script src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script>
{% endblock %}
{% block body %}
<form action="." method="post" enctype="multipart/form-data" class="form-horizontal">
{% csrf_token %}
<fieldset>
<legend><i class="icon-edit"></i>{% if object %} Изменить {% else %} Добавить {% endif %} файл</legend>
@ -10,7 +16,33 @@
<h2><i class="icon-pencil"></i> Основная информация</h2>
</div>
<div class="box-content">
{{ form.as_p }}
{# {{ form.as_p }}#}
{% with field='file_name' form=form languages=languages %}
{% include 'c_admin/forms/multilang.html' %}
{% endwith %}
<div class="control-group {% if form.file_path.errors %}error{% endif %}">
<label class="control-label">
<b>{{ form.file_path.label }}:</b>
</label>
<div class="controls">{{ form.file_path }}
<span class="help-inline">{{ form.file_path.errors }}</span>
</div>
</div>
<div class="control-group {% if form.purpose.errors %}error{% endif %}">
<label class="control-label">
<b>{{ form.purpose.label }}:</b>
</label>
<div class="controls">{{ form.purpose }}
<span class="help-inline">{{ form.purpose.errors }}</span>
</div>
</div>
{% with field='description' form=form languages=languages %}
{% include 'c_admin/forms/multilang.html' %}
{% endwith %}
</div>

@ -152,8 +152,8 @@
<div class="controls">
<button id="submit" class="btn btn-primary">Фильтровать</button>
<a href="{% url 'export_contacts' %}" id="export" class="btn yellow">Экспорт<i class="icon-circle-arrow-down"></i></a>
<a href="{% url 'newsletters_mailinglist_create_filter' %}" id="mailinglist" class="btn btn-success" data-toggle="tooltip" data-placement="top" title="Создает новый список рассылки с отфильтрованими контактами"><i class="icon-plus"></i>Создать список рассылки из фильтра</i></a>
<a href="{% url 'newsletters_mailinglist_create' %}" class="btn btn-success" data-toggle="tooltip" data-placement="top" title="Создает новый список рассылки"><i class="icon-plus"></i>Создать список рассылки</i></a>
<a href="{% url 'newsletters_mailinglist_create_filter' %}" id="mailinglist" class="btn btn-success" data-toggle="tooltip" data-placement="top" title="Создает новый список рассылки с отфильтрованими контактами"><i class="icon-plus"></i>Создать список рассылки из фильтра</a>
<a href="{% url 'newsletters_mailinglist_create' %}" class="btn btn-success" data-toggle="tooltip" data-placement="top" title="Создает новый список рассылки"><i class="icon-plus"></i>Создать список рассылки</a>
</div>
</div>
</div>

@ -65,6 +65,8 @@
<i class="icon-info-sign"></i>{% trans "Доступные параметры для прехедера" %}:
<p>{% trans "{name} - имя пользователя" %}</p>
<p>{% trans "{themes} - темы на которые пользователь подписан (первые 3 + кол-во оставшихся)" %}</p>
<i class="icon-info-sign"></i>{% trans "Доступные параметры для контента" %}:
<p>{% trans "{name} - имя пользователя" %}</p>
</div>
<div class="box-content">

@ -16,13 +16,13 @@
<script src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script>
{# google map не забыть скачать скрипты на локал #}
<link href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/redmond/jquery-ui.css' rel="stylesheet"/>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
{# <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>#}
<script src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js'></script>
<script src='https://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/formset_add.js' %}"></script>
{# <link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>#}
{# <script src="{% static 'js/select/select2.js' %}"></script>#}
{# <script src="{% static 'custom_js/formset_add.js' %}"></script>#}
{# ajax #}
<!-- <script src="{% static 'custom_js/file_post_ajax.js' %}"></script>-->

@ -10,7 +10,6 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<link rel="stylesheet" href="{% static 'mailing_settings/css/main.css' %}">
<link rel="stylesheet" href="{% static 'mailing_settings/css/form.css' %}">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js" defer></script>
</head>
@ -20,16 +19,16 @@
<header class="page_header">
<div class="container">
<div class="logo_block">
<a href="/"><img src="{% static 'mailing_settings/images/logo.png' %}" alt="Expomap"></a>
<a href="/" class="back_to_site">expomap.ru <span>&#8250;</span></a>
<a href="{% url 'index' %}"><img src="{% static 'mailing_settings/images/logo.png' %}" alt="Expomap"></a>
<a href="{% url 'index' %}" class="back_to_site">expomap.ru <span>&#8250;</span></a>
</div>
<h1>{% trans 'Настройте рассылку от Expomap' %}</h1>
<p>{% trans 'для' %} <span>{{ contact.email }}</span></p>
<p>{% trans 'для' %} <span>{{ object.email }}</span></p>
</div>
</header>
{% else %}
<header id="pr-header">
<div class="pr-center">
<div class="container">
<div class="pr-header-box">
<a class="pr-phone" href="tel:+7 (499) 999-12-07">+7 (499) 999-12-07</a>
<ul class="pr-social">
@ -41,13 +40,215 @@
<li><a href="https://twitter.com/expomap_ru"><img src="{% static 'mailing_settings/images/sm-icon-twit.png' %}" /></a></li>
</ul>
</div>
<strong class="pr-logo"><a href="/">Expomap</a></strong>
<strong class="pr-logo"><a href="{% url 'index' %}">Expomap</a></strong>
<span class="pr-slogan">{% blocktrans %}П<span class="pr-search-icon"></span>исковик деловых событий{% endblocktrans %}</span>
</div>
</header>
{% endif %}
<p>Страница в разработке</p>
<form action="." method="post" id="mailing_settings_form">
{% csrf_token %}
{% if not user.is_authenticated %}
<section id="pr-promo">
<div class="container">
<h1>{% trans 'Анонсы выставок' %} <br />{% trans 'и конференций на ваш e-mail' %}</h1>
<h2>{% trans 'Хотите быть в курсе событий?' %}</h2>
<div class="pr-promo-text">
<p>{% trans 'Получайте анонсы выставок и конференций на email каждую среду. Вы можете выбрать несколько интересующих вас тематических направлений.' %} <a target="_blank" href="{% url 'newsletter_test_letter' %}">{% trans 'Пример письма' %}</a></p>
</div>
<div class="pr-form">
<fieldset>
<div class="pr-row">
<span class="pr-input pr-name {% if form.first_name.errors %}field_error{% endif %}">
{% if form.first_name.errors %}<span class="text_error">{{ form.first_name.errors }}</span>{% endif %}
{{ form.first_name }}
</span>
<span class="pr-input pr-email {% if form.email.errors %}field_error{% endif %}">
{% if form.email.errors %}<span class="text_error">{{ form.email.errors }}</span>{% endif %}
{{ form.email }}
</span>
</div>
<button>{% trans 'Подписаться' %}</button>
</fieldset>
</div>
</div>
</section>
{% endif %}
<div class="themes_block">
<div class="container">
<h2>{% trans 'Какие события включать в ваше письмо?' %}</h2>
<div class="columns">
<div class="column">
<h3>{% trans 'Ваши темы:' %}</h3>
<ul id="selected_themes" class="selected selected_themes">
{% for theme in object.themes.all %}
<li data-id="{{ theme.pk }}" data-type="th" class="theme_{{ theme.pk }}">
<input type="hidden" name="th" value="{{ theme.pk }}">
{{ theme }}
<a href="#">&times;</a>
</li>
{% endfor %}
{% for tag in object.tags.all %}
<li data-id="{{ tag.pk }}" data-type="tg" data-parent="{{ tag.theme.pk }}" class="tag_{{ tag.pk }}">
<input type="hidden" name="tg" value="{{ tag.pk }}">
{{ tag }}
<a href="#">&times;</a>
</li>
{% endfor %}
</ul>
<a href="#search-modal" class="modal_trigger themes_trigger">{% trans 'Уточнить темы' %}</a>
</div>
<div class="column">
<h3>{% trans 'Ваши гео-фильтры:' %}</h3>
<ul class="geo_filters">
<li>
<label>
{{ form.moscow }}
<span class="label moscow">
<i class="fa fa-map-marker"></i>
{{ form.moscow.label }}
</span>
<span class="geo_checkbox"></span>
</label>
</li>
<li>
<label>
{{ form.russia }}
<span class="label rf">
<i class="fa fa-map-marker"></i>
{{ form.russia.label }}
</span>
<span class="geo_checkbox"></span>
</label>
<a href="#cities-modal" class="modal_trigger">{% trans 'Выбрать города' %}</a>
<ul id="selected_cities" class="selected"></ul>
{{ form.r_cities }}
</li>
<li>
<label>
{{ form.foreign }}
<span class="label foreign">
<i class="fa fa-map-marker"></i>
{{ form.foreign.label }}
</span>
<span class="geo_checkbox"></span>
</label>
<a href="#countries_modal" class="modal_trigger">{% trans 'Выбрать страны' %}</a>
<ul id="selected_areas" class="selected"></ul>
<ul id="selected_countries" class="selected"></ul>
{{ form.area }}
{{ form.co }}
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="subjects_block">
<div class="container">
<h2>{% trans 'Включать ли новости / обзоры / статьи в письмо?' %}</h2>
<div class="columns">
<div class="column">
{{ form.content_news }}
{{ form.content_news.label_tag }}
<p>{% trans "Получайте новости выставок и конференций по выбранным тематикам" %}</p>
</div>
<div class="column">
{{ form.content_overview }}
{{ form.content_overview.label_tag }}
<p>{% trans "Практические материалы, интервью, кейсы, которые помогут эффективно участвовать в выставках" %}</p>
</div>
<div class="column">
{{ form.content_articles }}
{{ form.content_articles.label_tag }}
<p>{% trans "Блог о том, как создавать и продвигать крутые event`ы" %}</p>
</div>
</div>
</div>
</div>
<div class="period_block">
<div class="container">
<h2>{% trans 'Регулярность получения писем' %}</h2>
<div class="columns">
<div class="column periodic">
<ul>
{% for field in form.periodic %}
<li>
<label>
{{ field.tag }}
<span class="radio">
{{ field.choice_label }}
</span>
</label>
</li>
{% endfor %}
</ul>
</div>
<div class="column mailing_day">
{% for field in form.periodic_day %}
<label>
{{ field.tag }}
<span class="radio">
{{ field.choice_label }}
</span>
</label>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="button_block">
<div class="container">
{% if not user.is_authenticated %}
<div class="tos">
<strong>{% trans 'Нажимая «Подписаться», вы соглашаетесь получать' %} <br /> {% trans 'материалы компании Expomap на свой электронный адрес' %} </strong>
<a href="{% url 'termsofuse' %}" style="color:#a2a2a2;">{% trans "Пользовательское соглашение" %}</a>
</div>
{% endif %}
<button type="submit">
{% if user.is_authenticated %}
{% trans "Сохранить" %}
{% else %}
{% trans 'Подписаться' %}
{% endif %}
</button>
{% if user.is_authenticated %}
<a href="?unsibscribe=1">{% trans 'Не хочу быть в курсе событий (отписаться от всего)' %}</a>
{% endif %}
</div>
</div>
</form>
<footer class="page_footer">&copy; Expomap {% now "Y" %}</footer>
<div class="modals">
<div id="search-modal">
{% include 'client/popups/new_themes.html' %}
</div>
<div id="cities-modal">
{% include 'client/popups/russia_cities.html' %}
</div>
<div id="countries_modal">
{% include 'client/popups/mailing_settings_countries.html' %}
</div>
{% if unsubscribe_success or unsubscribed %}
<div id="unsibscribed_modal">
{% include 'client/popups/unsubscribed.html' %}
</div>
{% endif %}
<div id="error_modal">
<div class="popup-window">
<header>
<div class="title">{% trans 'Ошибка' %}</div>
</header>
<div class="body error_messages" id="error_messages"></div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.4/jquery.fancybox.pack.min.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.min.js" defer></script>

@ -1,302 +1,301 @@
{% extends 'base_catalog.html' %}
{% load static %}
{% load i18n %}
{% load template_filters %}
{% block bread_scrumbs %}
<div class="bread-crumbs">
{% if object %}
<a href="/">{% trans 'Главная страница' %}</a>
<a href="{{ object.catalog }}">{% trans 'Выставки' %}</a>
<a href="{{ object.catalog }}country/{{ object.country.url }}/">{{ object.country }}</a>
<a href="{{ object.catalog }}city/{{ object.city.url }}/">{{ object.city }}</a>
<a href="{{ object.get_permanent_url }}">{{ object.name }}</a>
<strong>{% trans 'Участие в выставке' %}</strong>
{% else %}
<a href="/">{% trans 'Главная страница' %}</a>
<strong>{% trans 'Участие в выставке' %}</strong>
{% endif %}
</div>
{% endblock %}
{% block page_title %}
<div class="page-title">
<h1>{% if meta %}{{ meta.h1 }}{% else %}{% trans 'Участие в выставке' %}{% if object %} {{ object.name }} {% endif %}{% endif %}</h1>
</div>
{% endblock %}
{% block page_body %}
<div class="page-body clearfix request-form rq-participation">
<div class="m-article">
<div class="rq-info clearfix">
<div class="rqi-pict"><img src="{% static 'client/img/_del-temp/request-participation.png' %}" alt="" /></div>
<div class="rqi-body">
<h2>{% trans 'Увеличим эффективность Вашего участия в выставке' %}{% if object %} {{ object.name }} {% endif %} {% trans 'как минимум на 50%' %}</h2>
<div class="rqi-cols">
<ul>
<li>{% trans 'Мы поможем превратить посетителей стенда в клиентов' %}</li>
<li>{% trans 'Мы удержим Вас от пустых трат' %}</li>
<li>{% trans 'Мы посчитаем отдачу и покажем результаты в цифрах' %}</li>
</ul>
<ul>
<li>{% trans 'Мы начнем привлекать Вам клиентов еще до выставки' %}</li>
<li>{% trans 'Мы знаем тонкости и узкие места организации' %}</li>
</ul>
</div>
</div>
</div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}>
<form id="id_service_participation" method="post">{% csrf_token %}
<hr />
<div class="rq-form-sect">
<div class="rqf-title">{% trans 'Информация об экспоместе' %}</div>
<div class="mf-line cols-2">
<div class="mf-field rq-area-val validate-field{% if form.area.errors %} error-field{% endif %}">
<label>{% trans 'Требуемая площадь' %}:</label>
{{ form.area }}
<div class="error-blob">
{{ form.area.errors }}
</div>
</div>
<div class="mf-field rq-area-type validate-field{% if form.area_type.errors %} error-field{% endif %}">
<label>{% trans 'Вид площади' %}:</label>
{{ form.area_type }}
<div class="error-blob">
{{ form.area_type.errors }}
</div>
</div>
</div>
<div class="mf-line full-width">
<div class="mf-field">
{{ form.company_inf }}
</div>
</div>
</div>
<hr />
<div class="rq-form-sect">
<div class="rqf-title">{% trans 'Ваши контактные данные' %}</div>
{% if not object %}
<div class="mf-line rq-person ">
<div class="mf-field validate-field{% if form.event.errors %} error-field{% endif %}">
{{ form.event }}
<div class="error-blob">
{{ form.event.errors }}
</div>
</div>
</div>
{% endif %}
<div class="mf-line rq-person ">
<div class="mf-field validate-field{% if form.person_inf.errors %} error-field{% endif %}" >
{{ form.person_inf }}
<div class="error-blob">
{{ form.person_inf.errors }}
</div>
</div>
</div>
<div class="mf-line cols-2 rq-place">
<div class="mf-field rq-country validate-field{% if form.country.errors %} error-field{% endif %}">
{{ form.country }}
<div class="error-blob">
{{ form.country.errors }}
</div>
</div>
<div class="mf-field rq-city validate-field{% if form.city.errors %} error-field{% endif %}">
{{ form.city }}
<div class="error-blob">
{{ form.city.errors }}
</div>
</div>
</div>
<div class="mf-line cols-2 rq-contacts">
<div class="mf-field rq-tel validate-field{% if form.phone.errors %} error-field{% endif %}">
{{ form.phone }}
<div class="error-blob">
{{ form.phone.errors }}
</div>
</div>
<div class="mf-field rq-mail validate-field{% if form.person.errors %} error-field{% endif %}">
{{ form.person }}
<div class="error-blob">
{{ form.person.errors }}
</div>
</div>
</div>
</div>
<hr />
<div class="rq-btn-wrap">
{% if service.price %}
<input id="id_price" name="price" type="hidden" value="{{ service.price }}"/>
{% endif %}
{% if service.price %}
<input id="id_currency" name="currency" type="hidden" value="{{ service.currency }}"/>
{% endif %}
<button class="big orange a-more" type="submit">{% trans 'отправить запрос' %}</button>
</div>
</form>
</div>
<div class="rq-btn-wrap rq-btn-to-hide">
<a class="button big orange a-more" href="#">{% trans 'Сделать запрос' %}</a>
</div>
<hr />
<div class="rq-note">
{% if object %}
<p>
{% trans 'Укажите в запросе исходную информацию о Ваших целях и задачах, и мы подберем' %} {{ object.name }}
{% trans 'которая будет им соответствовать. Далее мы свяжемся с организаторами, чтобы уточнить наличие свободных площадей и цены, и вместе с Вами начнем создавать концепцию Вашего участия." На "Укажите в запросе исходную информацию о Ваших целях и задачах, и мы проанализируем, насколько' %} {{ object.name }}
{% trans 'им соответствует. Далее мы свяжемся с организаторами, чтобы уточнить наличие свободных площадей и цены, и вместе с Вами начнем создавать концепцию Вашего участия.' %}
</p>
{% else %}
<p>
{% trans 'Укажите в запросе исходную информацию о Ваших целях и задачах, и мы подберем выставку которая будет им соответствовать. Далее мы свяжемся с организаторами, чтобы уточнить наличие свободных площадей и цены, и вместе с Вами начнем создавать концепцию Вашего участия.'%}
</p>
{% endif %}
</div>
{% if messages %}
<div class="alert-message">
<ul>
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
{{ message }}
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
<div class="rq-to-hide">
<div class="s-comments">
<h2 class="sect-title">{% trans 'Отзывы клиентов' %}:</h2>
<div class="cat-list sc-comments">
<div class="cl-item">
<div class="cl-item-wrap clearfix">
<a target="_blank" href="#" data-type="href" data-hash="user_comment_logo_1"
class="link-encode"
data-url="{{ 'http://vezdevoz.ru'|base64_encode }}">
<div class="cli-pict"><img src="{% static 'client/img/comments/VEZDEVOZ.png' %}" alt="" /></div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title"><a target="_blank" href="#" data-type="href" data-hash="user_comment_1"
class="link-encode"
data-url="{{ 'http://vezdevoz.ru'|base64_encode }}">Vezdevoz</a></div>
</header>
</div>
<div class="sc-name">{% trans "Волкова Елизавета" %} </div>
<div class="sc-text">
{% trans "Хочу поблагодарить команду маркетологов Expomap за организацию нашего участия в выставке ТрансРоссия. Для нас это было чем-то новым, и благодаря опыту ребят мы избежали большого количества проблем и решали все возникающие вопросы очень оперативно. Если говорить о результатах работы на выставке, то мы собрали за 4 дня более 300 рабочих контактов и запросов, часть из которых выглядят очень перспективно. Мы сделали это вместе с Expomap и хотим сказать спасибо за их идеи, глубокое погружение в наши задачи, креативный подход и четкую помощь в реализации! Будем рады работать с вами и в других проектах!" %}
</div>
</div>
</div>
</div>
<div class="cl-item">
<div class="cl-item-wrap clearfix">
<a target="_blank" href="#" data-type="href" data-hash="user_comment_logo_2"
class="link-encode"
data-url="{{ 'http://www.sailfirst.com/ru/'|base64_encode }}">
<div class="cli-pict"><img src="{% static 'client/img/comments/Sail First.png' %}" alt="" /></div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title"><a target="_blank" href="#" data-type="href" data-hash="user_comment_2"
class="link-encode"
data-url="{{ 'http://www.sailfirst.com/ru/'|base64_encode }}">
MKM Sailing Center Ltd</a></div>
</header>
</div>
<div class="sc-name">Anatolios Spyrlidis</div>
<div class="sc-text">
{% trans "Мы принимали участие со своим стендом в выставке Boot Duesseldorf в Германии в январе 2014. Выражаем благодарность сотрудникам Expomap, а также персональному консультанту Руслану Шапилову за оперативность, мы остались довольны качеством оказанных услуг!" %}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="i-sub-articles">
<ul>
{% if object %}
<li><a href="{{ object.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a></li>
<li><a href="{{ object.get_permanent_url }}service/remote/">{% trans 'Заочное посещение' %}</a></li>
{% else %}
<li><a href="/service/visit/">{% trans 'Бизнес-тур «под ключ' %}»</a></li>
<li><a href="/service/translator/">{% trans 'Устный переводчик' %}</a></li>
<li><a href="/service/tickets/">{% trans 'Билеты на выставку' %}</a></li>
<li><a href="/service/remote/">{% trans 'Заочное посещение' %}</a></li>
{% endif %}
</ul>
</div>
{% if object %}
<div class="m-article">
{% include 'client/includes/booking_block.html' with city=object.city place=object.place event=object %}
</div>
{% endif %}
</div>
</div>
{% endblock %}
{% extends 'base_catalog.html' %}
{% load static %}
{% load i18n %}
{% load template_filters %}
{% block bread_scrumbs %}
<div class="bread-crumbs">
{% if object %}
<a href="/">{% trans 'Главная страница' %}</a>
<a href="{{ object.catalog }}">{% trans 'Выставки' %}</a>
<a href="{{ object.catalog }}country/{{ object.country.url }}/">{{ object.country }}</a>
<a href="{{ object.catalog }}city/{{ object.city.url }}/">{{ object.city }}</a>
<a href="{{ object.get_permanent_url }}">{{ object.name }}</a>
<strong>{% trans 'Участие в выставке' %}</strong>
{% else %}
<a href="/">{% trans 'Главная страница' %}</a>
<strong>{% trans 'Участие в выставке' %}</strong>
{% endif %}
</div>
{% endblock %}
{% block page_title %}
<div class="page-title">
<h1>{% if meta %}{{ meta.h1 }}{% else %}{% trans 'Участие в выставке' %}{% if object %} {{ object.name }} {% endif %}{% endif %}</h1>
</div>
{% endblock %}
{% block page_body %}
<div class="page-body clearfix request-form rq-participation">
<div class="m-article">
<div class="rq-info clearfix">
<div class="rqi-pict"><img src="{% static 'client/img/_del-temp/request-participation.png' %}" alt="" /></div>
<div class="rqi-body">
<h2>{% trans 'Увеличим эффективность Вашего участия в выставке' %}{% if object %} {{ object.name }} {% endif %} {% trans 'как минимум на 50%' %}</h2>
<div class="rqi-cols">
<ul>
<li>{% trans 'Мы поможем превратить посетителей стенда в клиентов' %}</li>
<li>{% trans 'Мы удержим Вас от пустых трат' %}</li>
<li>{% trans 'Мы посчитаем отдачу и покажем результаты в цифрах' %}</li>
</ul>
<ul>
<li>{% trans 'Мы начнем привлекать Вам клиентов еще до выставки' %}</li>
<li>{% trans 'Мы знаем тонкости и узкие места организации' %}</li>
</ul>
</div>
</div>
</div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}>
<form id="id_service_participation" method="post">{% csrf_token %}
<hr />
<div class="rq-form-sect">
<div class="rqf-title">{% trans 'Информация об экспоместе' %}</div>
<div class="mf-line cols-2">
<div class="mf-field rq-area-val validate-field{% if form.area.errors %} error-field{% endif %}">
<label>{% trans 'Требуемая площадь' %}:</label>
{{ form.area }}
<div class="error-blob">
{{ form.area.errors }}
</div>
</div>
<div class="mf-field rq-area-type validate-field{% if form.area_type.errors %} error-field{% endif %}">
<label>{% trans 'Вид площади' %}:</label>
{{ form.area_type }}
<div class="error-blob">
{{ form.area_type.errors }}
</div>
</div>
</div>
<div class="mf-line full-width">
<div class="mf-field">
{{ form.company_inf }}
</div>
</div>
</div>
<hr />
<div class="rq-form-sect">
<div class="rqf-title">{% trans 'Ваши контактные данные' %}</div>
{% if not object %}
<div class="mf-line rq-person ">
<div class="mf-field validate-field{% if form.event.errors %} error-field{% endif %}">
{{ form.event }}
<div class="error-blob">
{{ form.event.errors }}
</div>
</div>
</div>
{% endif %}
<div class="mf-line rq-person ">
<div class="mf-field validate-field{% if form.person_inf.errors %} error-field{% endif %}" >
{{ form.person_inf }}
<div class="error-blob">
{{ form.person_inf.errors }}
</div>
</div>
</div>
<div class="mf-line cols-2 rq-place">
<div class="mf-field rq-country validate-field{% if form.country.errors %} error-field{% endif %}">
{{ form.country }}
<div class="error-blob">
{{ form.country.errors }}
</div>
</div>
<div class="mf-field rq-city validate-field{% if form.city.errors %} error-field{% endif %}">
{{ form.city }}
<div class="error-blob">
{{ form.city.errors }}
</div>
</div>
</div>
<div class="mf-line cols-2 rq-contacts">
<div class="mf-field rq-tel validate-field{% if form.phone.errors %} error-field{% endif %}">
{{ form.phone }}
<div class="error-blob">
{{ form.phone.errors }}
</div>
</div>
<div class="mf-field rq-mail validate-field{% if form.person.errors %} error-field{% endif %}">
{{ form.person }}
<div class="error-blob">
{{ form.person.errors }}
</div>
</div>
</div>
</div>
<hr />
<div class="rq-btn-wrap">
{% if service.price %}
<input id="id_price" name="price" type="hidden" value="{{ service.price }}"/>
{% endif %}
{% if service.price %}
<input id="id_currency" name="currency" type="hidden" value="{{ service.currency }}"/>
{% endif %}
<button class="big orange a-more" type="submit">{% trans 'отправить запрос' %}</button>
</div>
</form>
</div>
<div class="rq-btn-wrap rq-btn-to-hide">
<a class="button big orange a-more" href="#">{% trans 'Сделать запрос' %}</a>
</div>
<hr />
<div class="rq-note">
{% if object %}
<p>
{% trans 'Укажите в запросе исходную информацию о ваших целях и задачах, и мы проанализируем, насколько' %} {{ object.name }}
{% trans 'им соответствует. Далее мы свяжемся с организаторами, чтобы уточнить наличие свободных площадей и цены, и вместе с вами начнем создавать концепцию вашего участия.' %}
</p>
{% else %}
<p>
{% trans 'Укажите в запросе исходную информацию о ваших целях и задачах, и мы проанализируем, насколько событие им соответствует. Далее мы свяжемся с организаторами, чтобы уточнить наличие свободных площадей и цены, и вместе с вами начнем создавать концепцию вашего участия.' %}
</p>
{% endif %}
</div>
{% if messages %}
<div class="alert-message">
<ul>
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
{{ message }}
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
<div class="rq-to-hide">
<div class="s-comments">
<h2 class="sect-title">{% trans 'Отзывы клиентов' %}:</h2>
<div class="cat-list sc-comments">
<div class="cl-item">
<div class="cl-item-wrap clearfix">
<a target="_blank" href="#" data-type="href" data-hash="user_comment_logo_1"
class="link-encode"
data-url="{{ 'http://vezdevoz.ru'|base64_encode }}">
<div class="cli-pict"><img src="{% static 'client/img/comments/VEZDEVOZ.png' %}" alt="" /></div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title"><a target="_blank" href="#" data-type="href" data-hash="user_comment_1"
class="link-encode"
data-url="{{ 'http://vezdevoz.ru'|base64_encode }}">Vezdevoz</a></div>
</header>
</div>
<div class="sc-name">{% trans "Волкова Елизавета" %} </div>
<div class="sc-text">
{% trans "Хочу поблагодарить команду маркетологов Expomap за организацию нашего участия в выставке ТрансРоссия. Для нас это было чем-то новым, и благодаря опыту ребят мы избежали большого количества проблем и решали все возникающие вопросы очень оперативно. Если говорить о результатах работы на выставке, то мы собрали за 4 дня более 300 рабочих контактов и запросов, часть из которых выглядят очень перспективно. Мы сделали это вместе с Expomap и хотим сказать спасибо за их идеи, глубокое погружение в наши задачи, креативный подход и четкую помощь в реализации! Будем рады работать с вами и в других проектах!" %}
</div>
</div>
</div>
</div>
<div class="cl-item">
<div class="cl-item-wrap clearfix">
<a target="_blank" href="#" data-type="href" data-hash="user_comment_logo_2"
class="link-encode"
data-url="{{ 'http://www.sailfirst.com/ru/'|base64_encode }}">
<div class="cli-pict"><img src="{% static 'client/img/comments/Sail First.png' %}" alt="" /></div>
</a>
<div class="cli-info">
<div class="cli-top clearfix">
<header>
<div class="cli-title"><a target="_blank" href="#" data-type="href" data-hash="user_comment_2"
class="link-encode"
data-url="{{ 'http://www.sailfirst.com/ru/'|base64_encode }}">
MKM Sailing Center Ltd</a></div>
</header>
</div>
<div class="sc-name">Anatolios Spyrlidis</div>
<div class="sc-text">
{% trans "Мы принимали участие со своим стендом в выставке Boot Duesseldorf в Германии в январе 2014. Выражаем благодарность сотрудникам Expomap, а также персональному консультанту Руслану Шапилову за оперативность, мы остались довольны качеством оказанных услуг!" %}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="i-sub-articles">
<ul>
{% if object %}
<li><a href="{{ object.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a></li>
<li><a href="{{ object.get_permanent_url }}service/remote/">{% trans 'Заочное посещение' %}</a></li>
{% else %}
<li><a href="/service/visit/">{% trans 'Бизнес-тур «под ключ' %}»</a></li>
<li><a href="/service/translator/">{% trans 'Устный переводчик' %}</a></li>
<li><a href="/service/tickets/">{% trans 'Билеты на выставку' %}</a></li>
<li><a href="/service/remote/">{% trans 'Заочное посещение' %}</a></li>
{% endif %}
</ul>
</div>
{% if object %}
<div class="m-article">
{% include 'client/includes/booking_block.html' with city=object.city place=object.place event=object %}
</div>
{% endif %}
</div>
</div>
{% endblock %}

Loading…
Cancel
Save