Ejemplo n.º 1
0
    def find_rules_by_url(self, request):
        url = request.GET.get('url')

        if url:
            from ad.models import Region
            url_data = Region.get_region_and_params_from_url(url)

            deal_type = url_data['kwargs'].get('deal_type', 'index')
            property_type = url_data['kwargs'].get('property_type', 'default')
            region = url_data['region'] or url_data['subdomain_region']
            rooms = url_data['GET'].get('rooms', None)
            subway = url_data['GET'].get('subway', None)

            subpage = url_data['view'].__name__
            if subpage  == 'search':
                subpage = 'default'

            # устанавлием язык запрашиваемой страницы
            translation.activate(url_data['language'])

            # получаем список подходящих правил и словарь метатегов
            rules, seo = SEORule.get_suitable_rules(region, deal_type, property_type, subpage, rooms, subway)

            # возвращаем язык админки
            translation.activate(request.LANGUAGE_CODE)

        return render(request, "admin/seo/find_rules.html", locals())
Ejemplo n.º 2
0
def lead(request):
    title = _(u'Оплата за звонок')
    selected_province = Region.get_capital_province()

    if request.user.is_authenticated:
        if request.user.region:
            selected_province = request.user.region

        user_recipient = request.user
        if 'realtor' in request.GET:
            user_recipient = user_recipient.get_own_agency().get_realtors(
            ).get(pk=request.GET['realtor']).user

        leadgeneration = request.user.get_leadgeneration() or LeadGeneration(
            user=request.user)
        leadgeneration_form = LeadGenerationForm(instance=leadgeneration)

    lead_prices = {}
    for lead_type in ['call', 'callrequest']:
        for deal_type in ['sale', 'rent', 'rent_daily']:
            lead_prices['%s_%s' % (lead_type, deal_type)] = get_lead_price(
                lead_type, deal_type, selected_province.price_level)
    active_proxynumbers = ProxyNumber.objects.filter(
        is_shared=False, user__isnull=True).count()
    reviews = Review.objects.all()

    return render(request, 'ppc/lead.jinja.html', locals())
Ejemplo n.º 3
0
def update_region(user=None):
    # для областей get_children_ids() возвращает большие списки - нужна оптимизация с set()
    provinces_children = {
        province.id: set(province.get_children_ids())
        for province in Region.get_provinces()
    }

    counters = collections.defaultdict(collections.Counter)

    if user:
        query = Ad.objects.filter(user=user)
    else:
        query = Ad.objects.filter(user__isnull=False)

    for row in query.values(
            'user', 'region').annotate(ads_count=Count('region')).order_by():
        for province_id, children in provinces_children.iteritems():
            if row['region'] in children:
                counters[row['user']][province_id] += row['ads_count']

    updated = 0
    for user in User.objects.filter(id__in=counters.keys()):
        common_region = counters[user.id].most_common(1)[0][0]
        if user.region_id != common_region:
            user.region_id = common_region
            user.save()
            updated += 1

    return updated
Ejemplo n.º 4
0
 def lookups(self, request, model_admin):
     values = cache.get('filter_byprovince')
     if not values:
         values = [(str(region.pk), region.name)
                   for region in Region.get_provinces()]
         cache.set('filter_byprovince', values, 3600 * 24)
     return values
Ejemplo n.º 5
0
    def process_request(self, request):
        request.provinces = Region.get_provinces()
        request.subdomains = Region.get_subdomains()

        if request.subdomains:
            for region in request.subdomains:
                if region.slug == request.subdomain or (region.static_url == ';' and request.subdomain is None):
                    request.subdomain_region = region
                    break
            else:
                from django_hosts.resolvers import reverse
                return HttpResponseRedirect(reverse('index'))
        else:
            raise Exception('No subdomains')  # чтобы не было бесконечных редиректов

        if request.subdomain == 'international':
            request.provinces = request.subdomain_region.get_children().order_by('name')
Ejemplo n.º 6
0
def subscription(request):
    if request.user.is_authenticated():
        user_province = request.user.region
    else:
        user_province = Region.get_capital_province()

    provinces = Region.get_provinces()
    for province in provinces:
        # Волынская, Закарпатская, Кировоградская, Полтавская, Ровенская, Сумская, Тернопольская, Черкасская, Донецкая, Крым, Луганская
        if province.id in [270, 189, 2, 92, 283, 240, 631, 15, 43, 11994, 19]:
            province.zone = 'low'
        # Винницкая, Житомирская, Запорожская, Ивано-Франковская, Львовская, Николаевская, Херсонская, Хмельницкая, Черниговская, Черновицкая
        elif province.id in [29, 51, 55, 60, 90, 122, 173, 62, 12, 233]:
            province.zone = 'med'
        else:
            province.zone = 'high'

    base_price = 25 * 1.2  # базовая цена за размещение одного объявления 25 грн без учета НДС
    discount = 67  # скидка при покупке в текущем месяце

    prices_by_zone = collections.defaultdict(list)
    for zone, zone_coefficient in {'low': 0.5, 'med': 0.75, 'high': 1}.items():
        price_for_one_ad = int(math.ceil(base_price * zone_coefficient))

        for ads_count in [1, 5, 10, 20, 30, 40]:
            if ads_count == 1:
                label = u'1 объявление'
                price = price_for_one_ad
            else:
                label = u'до %s объявлений' % ads_count
                price = price_for_one_ad / 2.0 * ads_count

            prices_by_zone[zone].append([
                label,
                int(math.ceil(price)),
                int(math.ceil(math.ceil(price) * (100 - discount) / 100))
            ])

    faq_articles = {}
    for category_id in [2, 3, 9, 10]:
        faq_articles[category_id] = FAQArticle.objects.filter(
            category=category_id, is_published=True)

    return render(request, 'promo/index2.jinja.html', locals())
Ejemplo n.º 7
0
def fastcheck(request):

    # дубли поддоменов
    subdomain_errors = []
    for subdomain in Region.get_subdomains():
        similar_regions = Region.objects.filter(name=subdomain.name, kind=subdomain.kind).exclude(id=subdomain.id)
        for region in similar_regions:
            # ID 11244 - Львовская область, Николаевский район, Николаев
            if region.id != 11244:
                subdomain_errors.append((subdomain, region))

    return render(request, "admin/fastcheck.html", locals())
Ejemplo n.º 8
0
def detail(request, property_type, id, regions_slug=None):
    region  = Region.get_region_from_slug(regions_slug, '' if request.subdomain == 'bank' else request.subdomain, request.subdomain_region)
       
    banks = Bank.objects.filter(is_active=True, logo__gt='')

    ad_property_types = convert_to_ad(property_type)

    try:
        item = Ad.objects.select_related('region').prefetch_related('photos').get(id=id, bank__isnull=False, property_type__in=ad_property_types)
        usercard = item.prepare_usercard(host_name=request.host.name)
    except (Ad.DoesNotExist, Http404, IndexError) :
        raise Http404
    
    if not region or (request.subdomain_region.kind != 'group' and item.region and item.region.static_url != region.static_url) :
        return redirect(item.get_bank_url())

    # на поддомене с группой регионов не проверяем корректность URL и региона в нем or \
    # исключаем объявления заблокированных пользователей и сами забаненные объявления
    if (item.status == 200 or not item.region or (item.user and item.user.pk in get_banned_users())):
        raise Http404

    # считаем просмотры
    updated_rows = ViewsCount.objects.filter(basead=item, date=datetime.date.today(), is_fake=False).update(detail_views=F('detail_views')+1)
    if not updated_rows:
        ViewsCount.objects.create(basead=item, date=datetime.date.today(), detail_views=1)
    
    item.image_title = image_title(item)
    title = item.address # TODO: добавить тип сделки к урлу
    
    if request.user.is_authenticated():
        item.saved = SavedAd.objects.filter(user=request.user, basead=item).count()
    
    callback_form = CallbackForm(initial={'property_id':item.id})
    csrf_token = get_token(request)
    
    return render(request, 'bank/detail.html', locals())
Ejemplo n.º 9
0
    def purchase_plan(self, plan, move_money_from_user=None, order=None):
        from paid_services.views import get_plan_action  # TODO: надо избавиться от этого, но мешают хаки с подменой active_plan, например, в profile.views_plans.plan
        active_plan = self.get_active_plan()
        action = get_plan_action(plan, active_plan)
        region = self.region or Region.get_capital_province()
        price = Plan.get_price(region.price_level, plan.ads_limit,
                               self.get_plan_discount())
        unexpired_plans = self.get_unexpired_plans().order_by('-end')

        try:
            if action:
                if action == 'purchase':
                    transaction = Transaction.objects.create(user=self,
                                                             type=11,
                                                             amount=-price,
                                                             order=order)
                    purchased_userplan = UserPlan.objects.create(
                        user=self,
                        plan=plan,
                        ads_limit=plan.ads_limit,
                        region=region)
                if action == 'prolong':
                    transaction = Transaction.objects.create(
                        user=self,
                        type=11,
                        amount=-price,
                        order=order,
                        comment=u'продление для тарифа #%d' % active_plan.id)
                    purchased_userplan = UserPlan.objects.create(
                        user=self,
                        plan=plan,
                        ads_limit=plan.ads_limit,
                        region=region,
                        start=unexpired_plans[0].end,
                        is_active=False)
                if action == 'upgrade':
                    for unexpired_plan in unexpired_plans:
                        unexpired_plan.cancel(self)

                    active_plan.cancel(self)
                    transaction = Transaction.objects.create(user=self,
                                                             type=11,
                                                             amount=-price,
                                                             order=order)
                    purchased_userplan = UserPlan.objects.create(
                        user=self,
                        plan=plan,
                        ads_limit=plan.ads_limit,
                        region=region)

                Transaction.objects.filter(id=transaction.id).update(
                    user_plan=purchased_userplan)
            else:
                raise Exception('User #%d can not buy plan #%d' %
                                (self.id, plan.id))

        except InsufficientFundsError as insufficient_funds_error:
            if move_money_from_user:
                Transaction.move_money(move_money_from_user, self,
                                       insufficient_funds_error.deficit,
                                       u'для покупки тарифа риелтором')
                self.purchase_plan(plan)
            else:
                raise
Ejemplo n.º 10
0
    def decorated_view(request, *args, **kwargs):
        title = _(u'Подтверждение заказа')

        # Делаем копию словаря, т.к. при работе с VIP у нас есть необходимость добавлять тарифный план к покупке
        request_get = request.GET.copy()

        if 'realtor' in request_get:
            user_recipient = request.user.get_own_agency().get_realtors().get(
                pk=request_get['realtor']).user
        else:
            user_recipient = request.user

        # берется общий баланс риелтора и админа, чтобы знать нужно ли будет переводить на платежную систему
        # или хватит перевода денег с админского аккаунта
        balance = request.user.get_balance(force=True)
        if user_recipient != request.user:
            balance += user_recipient.get_balance(force=True)

        region = user_recipient.region or Region.get_capital_province()

        if 'ads' in request_get:
            ads = Ad.objects.filter(
                id__in=request_get['ads'].split(','),
                user__in=user_recipient.get_owned_users(request))
        else:
            ads = Ad.objects.none()

        total_amount = 0
        payback = 0

        # VIP
        if 'vip' in request_get:
            ads_to_vip = ads.exclude(pk__in=VipPlacement.objects.filter(
                is_active=True).values('basead'))
            vips_amount = sum(
                user_recipient.get_paidplacement_price(ad, 'vip')
                for ad in ads_to_vip)
            total_amount += vips_amount

            # Если не хватает активного плана для работы с VIP на время действия VIP,
            # то предлагаем пролонгацию плана
            user_plan = user_recipient.get_active_plan()
            if user_plan is not None and user_plan.get_days_to_finish() < 7:
                request_get['plan'] = user_plan.plan_id

        # зарубежные каталоги
        selected_catalogs = request_get.getlist('intl_catalog')
        if selected_catalogs:
            # TODO international_crutch: убрать поднятие зарубежных объявления при работе тарифа
            # для международной недвижимости нет тарифов
            plans = None

            intl_catalogs = {
                'intl_mesto': {
                    'name':
                    _(u'Размещение зарубежной недвижимости на сайте mesto.ua'),
                    'amount':
                    0
                },
                'worldwide': {
                    'name': _(u'Размещение в международных каталогах'),
                    'amount': 0
                },
            }

            ads_to_intl = ads.exclude(
                id__in=CatalogPlacement.get_active_user_ads())

            # для недвижимости на украине размещения на нашем сайте бесплатно
            if ads_to_intl.exists() and ads_to_intl[0].addr_country == 'UA':
                del intl_catalogs['intl_mesto']

            # недвижимость вне украины мы не можем публиковать на сайтах-партнеров
            if ads_to_intl.exists() and ads_to_intl[0].addr_country != 'UA':
                del intl_catalogs['worldwide']

            # подсчет стоимостьи размещения объявлений в каждом каталоге
            for catalog in intl_catalogs:
                for ad in ads_to_intl:
                    intl_catalogs[catalog][
                        'amount'] += user_recipient.get_paidplacement_price(
                            ad, catalog)

            # подсчитываем итоговую стоимость выбранный каталогов(для purchase)
            for catalog in selected_catalogs:
                total_amount += intl_catalogs[catalog]['amount']

        # тарифы
        if 'plan' in request_get:
            plan = user_recipient.get_available_plans().get(
                id=request_get['plan'])

            active_plan = user_recipient.get_active_plan()
            unexpired_plans = user_recipient.get_unexpired_plans().order_by(
                '-end')

            plan_action = get_plan_action(plan, active_plan)

            if plan_action:
                if plan_action == 'prolong':
                    purchase_time = unexpired_plans[0].end
                    discount = user_recipient.get_plan_discount(purchase_time)
                else:
                    discount = user_recipient.get_plan_discount()

                if plan_action == 'upgrade':
                    payback = active_plan.get_payback()
                else:
                    payback = 0

                plan_price = Plan.get_price(region.price_level, plan.ads_limit,
                                            discount)
                plan_price_with_payback = plan_price - payback
                total_amount += plan_price
            else:
                raise Exception('Cannot upgrade plan from #%d to #%d' %
                                (active_plan.plan.id, plan.id))

        request.checkout_options = locals()

        return func(request, *args, **kwargs)
Ejemplo n.º 11
0
def detail(request, deal_type, id, region_slug=None, property_type=None):
    newhome_id = id
    region = Region.get_region_from_slug(region_slug, request.subdomain,
                                         request.subdomain_region)

    try:
        newhome = Newhome.objects.select_related('region').prefetch_related(
            'newhome_photos').get(id=newhome_id)

    except (Newhome.DoesNotExist, Http404, IndexError):
        return HttpResponseGone(
            render_to_string('410.jinja.html', locals(), request=request))

    if not newhome.user.leadgeneration.is_shown_users_phone:
        callrequest_form = get_callrequest_form(request, newhome.pk)

    # подобные новостройки
    # similar_newhomes = Ad.objects.filter(deal_type='newhomes', status=1, region__in=request.subdomain_region.get_descendants(True))\
    #                        .exclude(pk=newhome.pk).select_related('region').prefetch_related('photos')[:4]
    similar_newhomes = []

    # Информация по этажам и квартирам
    (flats_rooms_options, flats_available, flats_prices_by_floor,
     flats_info_exists, flats_floor_options, flats_area_by_rooms,
     flats_prices_by_rooms,
     currency) = newhome.get_aggregation_floors_info(request)

    # ход строительства
    progress, progress_next, progress_prev = newhome.get_progress(
        request.GET.get('progress'))

    # на поддомене с группой регионов проверяем корректность URL и региона в нем
    # todo: может вынести в декоратор?
    if deal_type != 'newhomes' or not region and newhome.region \
            or (request.subdomain_region.kind != 'group' and newhome.region and newhome.region.static_url != region.static_url):
        return redirect(newhome.get_absolute_url())

    # исключаем объявления заблокированных пользователей и сами забаненные объявления + объявления робота
    if (newhome.status != 1 or
        (newhome.user_id
         and newhome.user_id in get_banned_users())) or not newhome.region:
        shown_only_for_you = [
            request.user.is_staff,
            request.user.has_perm('newhome.newhome_admin'),
            request.user.is_authenticated()
            and request.user.id == newhome.user_id,

            # Удаленные открываем только для админов
            newhome.status == 211 and any([
                request.user.is_staff,
                request.user.has_perm('newhome.newhome_admin')
            ])
        ]

        # можно показать объявление владельцу или админу
        if not any(shown_only_for_you):
            messages.error(
                request,
                _(u'На данный момент выбранный Вами объект недоступен. Пожалуйста, выберите из списка доступных'
                  ))
            return HttpResponseRedirect(
                reverse('ad-search', kwargs={'deal_type': 'newhomes'}))

    # Готовим SEO
    title, description = get_details_newhome_metatags(region, newhome)

    # Телефон показываем только при балансе большем чем за одного лида у застройщика
    if (newhome.user.leadgeneration.is_shown_users_phone
            or newhome.user.get_balance() > get_lead_price(
                'call', 'newhomes', 'high')):
        developer_phone = ProxyNumber.get_numbers(newhome.user, 'newhomes',
                                                  request.traffic_source,
                                                  newhome)[0]

    else:
        developer_phone = None

    crosslinks_blocks = get_crosslinks(request.build_absolute_uri(),
                                       region,
                                       'newhomes',
                                       'flat',
                                       current_language=request.LANGUAGE_CODE,
                                       detail=True)

    return render(request, 'newhome/detail.jinja.html', locals())
Ejemplo n.º 12
0
def search(request,
           deal_type,
           region_slug=None,
           property_type=None,
           subway_slug=None):
    region = Region.get_region_from_slug(region_slug, request.subdomain,
                                         request.subdomain_region)
    if not region:
        raise Http404

    if property_type is not None:
        return HttpResponsePermanentRedirect(
            request.path_info.replace('-%s/' % property_type, ''))

    property_type = 'flat'
    request.GET = clear_get(request, region, deal_type, property_type,
                            request.GET.copy())
    if request.GET.get('redirect'):
        return HttpResponsePermanentRedirect(request.GET.get('redirect'))

    # выбор региона для селектора населенного пункта в форме
    region_for_search = region
    for parent in region.get_parents()[::-1]:
        if parent.kind in ['country', 'province', 'village', 'locality']:
            region_for_search = parent
            break

    # чтобы в форме это метро было выделено
    if subway_slug is not None:
        subway_station = get_object_or_404(SubwayStation, slug=subway_slug)
        get_dict = dict(request.GET.lists())
        if 'subway_stations' in get_dict:
            if str(subway_station.id) not in get_dict['subway_stations']:
                request.GET.appendlist('subway_stations',
                                       str(subway_station.id))
        else:
            request.GET.appendlist('subway_stations', str(subway_station.id))

    # теперь данные из region_slug нужно запихнуть в GET, чтобы в форме этот район тоже был выделен
    if region.kind == 'district':
        request.GET.appendlist('district', region.id)

    # весь список опубликованных активных объектов
    base_items_list = Newhome.objects.filter(status=1,
                                             is_published=True).order_by(
                                                 '-modified', '-pk')

    try:
        # копия GET-словаря нужна, т.к. ниже она модифицируется через form.data
        form = NewhomeSearchForm(request.GET)
        form.prepare_choices(region_for_search)

        # города и области, в которых есть новостройки
        # TODO: возможно, есть смысл сделать поле "город/область" у новостройки для упрощения алгоритма
        cities_with_newhomes = []
        cities_with_newhomes_in_province = []

        main_cities = Region.objects.get(
            static_url=';').get_descendants().filter(
                main_city=True).prefetch_related('parent')
        for city in main_cities:
            if city.parent.kind != 'province':
                raise Exception('Parent of city #%d is not province' % city)

        for path in Newhome.objects.filter(region__isnull=False,
                                           is_published=True).values_list(
                                               'region__tree_path',
                                               flat=True).distinct():
            ids_in_path = [int(region_id) for region_id in path.split('.')]
            for city in main_cities:
                if city.id in ids_in_path:
                    if city not in cities_with_newhomes:
                        cities_with_newhomes.append(city)
                elif city.parent.id in ids_in_path and city not in cities_with_newhomes_in_province:
                    cities_with_newhomes_in_province.append(city)

        cities_with_newhomes.sort(key=lambda obj: obj.name)

    except Region.DoesNotExist:
        # не найден активный регион в выпадающем списке
        return redirect('..')

    # тип недвижимости берется из URL, а не из параметров GET
    form.data['deal_type'] = deal_type
    form.data['property_type'] = property_type

    region_filter_applied = False
    rooms_filter_for_seo = 0
    subway_filter_for_seo = 0
    filtered_by_region_search = False
    show_developer_intro = True

    if form.is_valid():
        items_list = NewhomePropertyFilter(form.cleaned_data,
                                           queryset=base_items_list).qs

        show_developer_intro = bool(
            filter(lambda key_: form.cleaned_data[key_],
                   ['name', 'developer', 'rooms', 'subway_stations']))

        region_filter_applied = bool(
            filter(lambda key_: form.cleaned_data[key_],
                   ['region_search', 'addr_street_id', 'district']))

        if len(form.cleaned_data['rooms']) == 1:
            rooms_filter_for_seo = form.cleaned_data['rooms'][0]

        if form.cleaned_data['subway_stations']:
            subway_filter_for_seo = form.cleaned_data['subway_stations'][0]

        for city in cities_with_newhomes:
            if region.id == city.id:
                if form.cleaned_data['region_search']:
                    items_list = items_list.filter(
                        region__in=city.parent.get_descendants(
                            include_self=True)).exclude(
                                region__in=city.get_descendants(
                                    include_self=True))

                    filtered_by_region_search = True
                    region_filter_applied = True
                else:
                    items_list = items_list.filter(
                        region__in=city.get_descendants(include_self=True))
                break
            else:
                items_list = items_list.filter(
                    region__in=region.get_descendants(include_self=True))
    elif request.GET:
        items_list = Newhome.objects.none()
    else:
        items_list = base_items_list

    # применяем фильтр по регионам, если не применились фильтры по району/улице
    if not region_filter_applied:
        if region.kind == 'country' and region.slug == 'ukraina':
            pass

        elif not filtered_by_region_search:
            province = region.get_ancestors().filter(kind='province').first()

            # Добавлен 301 редирект на старые ссылки, что хранятся у поисковиков
            if province is None:
                return HttpResponsePermanentRedirect('/newhomes/')

            items_list = items_list.filter(
                region__in=province.get_descendants(True))

    # todo: временно убрано, т.к. данные не готовы к таким координальным переменам
    # todo: Prefetch('newhome_photos', queryset=NewhomePhoto.objects.filter(is_main=True))
    items_list = items_list.annotate(
        balance=Sum('user__transactions__amount')).filter(
            balance__gt=0).prefetch_related('newhome_photos', 'region')
    paginator = AdPaginator(items_list, 20, request=request)

    seo_klass = SEO(current_language=request.LANGUAGE_CODE)
    seo = seo_klass.get_seo(region=region,
                            deal_type=deal_type,
                            property_type=property_type,
                            rooms=rooms_filter_for_seo,
                            subway_stations=subway_filter_for_seo)

    seo_text_block = TextBlock.find_by_request(request, region)

    # генерация (без сохранения) текствого блока для страниц улиц
    if not seo_text_block:
        seo_text_block = TextBlock.generate_text_block(request, deal_type,
                                                       property_type, region)

    # блоки ссылок для перелинковки (SEO от октября 2014)
    crosslinks_blocks = get_crosslinks(request.build_absolute_uri(),
                                       region,
                                       'newhomes',
                                       property_type,
                                       rooms=rooms_filter_for_seo,
                                       subway_station=subway_filter_for_seo,
                                       current_language=request.LANGUAGE_CODE,
                                       scp=seo_klass.scp)

    show_developer_intro = paginator.current_page_number == 1 and show_developer_intro

    # отображение похожих результатов поиска
    related_results = None
    related_newhomes = None
    if form.is_valid(
    ) and paginator.current_page_number == 1 and not paginator.current_page.object_list:
        related_newhomes = search_newhome_related(base_items_list, region,
                                                  form.cleaned_data)

        base_items_list = Ad.objects.filter(
            is_published=True,
            deal_type='sale').exclude(get_exclude_rules()).prefetch_related(
                'photos', 'region').order_by('-vip_type', '-updated', '-pk')

        form.cleaned_data.update({'property_type': 'flat'})
        related_results = search_related(base_items_list, 'sale',
                                         property_type, region,
                                         form.cleaned_data)

    response_status = None
    if not form.is_valid() or not len(paginator.current_page.object_list):
        response_status = 404

    return render(request,
                  'newhome/search.jinja.html',
                  locals(),
                  status=response_status)
Ejemplo n.º 13
0
def statistics_analysis_disclosed_contacts(user_email, start_at, finish_at):
    task_logger.debug('statistics_analysis_disclosed_contacts: start')
    regions = Region.get_provinces()
    start_at = datetime.datetime.combine(start_at, datetime.time.min)
    finish_at = datetime.datetime.combine(finish_at, datetime.time.max)
    date_range = (start_at, finish_at)

    book = xlwt.Workbook(encoding='utf8')
    font = xlwt.Font()
    font.bold = True
    bold_style = xlwt.XFStyle()
    bold_style.font = font
    sheet = book.add_sheet(u'Лист 1')
    user_columns = [
        u'Период отчета', u'Тип сделки', u'Region_type', u'Region_full',
        u'Кол-во активных пакетов ', u'Кол-во обьявлений (по подписке)',
        u'Кол-во взятых контактов', u'Контактов на обьявление',
        u'Кол-во клиентов на ППК', u'Кол-во обьявлений ППК', u'Кол-во звонков',
        u'Кол-во пропущеных', u'Кол-во заявок', u'Возвратов',
        u'Итого действий', u'Звонков на обьявление'
    ]
    [
        sheet.write(0, k, v, style=bold_style)
        for k, v in enumerate(user_columns)
    ]

    google_analytics_ads = {}
    path = 'statistics_analysis_disclosed_contacts.csv'
    if default_storage.exists(path):
        with default_storage.open(path, 'rb+') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=';')
            re_url = re.compile(r'/(\d+)\.html')
            for row in csv_reader:
                parsed_url = re_url.search(row[0])
                if parsed_url:
                    google_analytics_ads[int(parsed_url.group(1))] = int(
                        row[1])

            task_logger.debug(
                'statistics_analysis_disclosed_contacts: working with data')
            position = 1
            period = u'%s - %s' % (start_at.strftime('%d.%m'),
                                   finish_at.strftime('%d.%m'))
            for region in regions:
                region_full = u'%s' % region.name
                regions_children_ids = region.get_children_ids()
                users_id = list(
                    User.objects.filter(region=region).values_list('id',
                                                                   flat=True))

                range_filter = Q(start__range=date_range) | Q(
                    end__range=date_range) | Q(start__lt=start_at,
                                               end__gt=finish_at)

                active_plans_amount = UserPlan.objects.filter(
                    Q(user__id__in=users_id) & range_filter).count()
                active_properties_amount = sum(
                    Stat.objects.filter(user__id__in=users_id,
                                        date__range=date_range).values_list(
                                            'active_properties', flat=True)
                    or [0])
                active_ads = int(
                    float(active_properties_amount) / float(
                        (finish_at - start_at).days))

                ppc_users_id = set(
                    ActivityPeriod.objects.filter(
                        Q(user__id__in=users_id) & range_filter).values_list(
                            'user_id', flat=True))
                ppc_amount = len(ppc_users_id)
                ads_ppc_amount = sum(
                    Stat.objects.filter(user__id__in=ppc_users_id,
                                        date__range=date_range).values_list(
                                            'active_properties', flat=True)
                    or [0])

                calls = 0
                missed_calls = 0
                requests = 0
                returned = 0
                ap_list = ActivityPeriod.objects.filter(
                    Q(user__id__in=users_id) & range_filter)
                for ap in ap_list:
                    calls += ap.user.answered_ppc_calls.filter(
                        call_time__range=date_range).count()
                    missed_calls += ap.user.answered_ppc_calls.filter(
                        call_time__range=date_range, duration=0).count()
                    requests += ap.user.callrequests_to.filter(
                        time__range=date_range).count()
                    returned += ap.user.answered_ppc_calls.filter(
                        call_time__range=date_range,
                        complaint__isnull=False).count()

                result = calls + missed_calls + requests - returned

                for deal_type in ['sale', 'rent', 'rent_daily']:
                    ads_id = set(
                        Ad.objects.filter(region__in=regions_children_ids,
                                          pk__in=google_analytics_ads.keys(),
                                          deal_type=deal_type).values_list(
                                              'pk', flat=True))
                    cont_add = sum([
                        val for key, val in google_analytics_ads.iteritems()
                        if key in ads_id
                    ])
                    cont_adv = float(
                        PhoneInAd.objects.filter(basead__in=ads_id).count()
                    ) / len(ads_id) if ads_id else 0

                    zadv = float(calls +
                                 missed_calls) / len(ads_id) if ads_id else 0

                    sheet.write(position, 0, period)
                    sheet.write(position, 1, deal_type)
                    sheet.write(position, 2, region.price_level)
                    sheet.write(position, 3, region_full)
                    sheet.write(position, 4, active_plans_amount)
                    sheet.write(position, 5, active_ads)
                    sheet.write(position, 6, cont_add)
                    sheet.write(position, 7,
                                float(u"{0:.2f}".format(cont_adv)))
                    sheet.write(position, 8, ppc_amount)
                    sheet.write(position, 9, ads_ppc_amount)
                    sheet.write(position, 10, calls)
                    sheet.write(position, 11, missed_calls)
                    sheet.write(position, 12, requests)
                    sheet.write(position, 13, returned)
                    sheet.write(position, 14, result)
                    sheet.write(position, 15, float(u"{0:.2f}".format(zadv)))
                    position += 1

            buffer_io = StringIO.StringIO()
            book.save(buffer_io)

            # Отправляем отчет
            message = EmailMessage(subject=u"Анализ расскрытых контактов",
                                   body=u"Файл с отчетом во вложении",
                                   to=[user_email])
            message.attach('report.xls', buffer_io.getvalue(),
                           "application/vnd.ms-excel")
            message.send()

            task_logger.debug('statistics_analysis_disclosed_contacts: finish')

    else:
        task_logger.debug(
            'statistics_analysis_disclosed_contacts: error open file %s' %
            path)
Ejemplo n.º 14
0
def statistics_by_province(request):
    if not request.user.has_perm("%s.%s_%s" %
                                 ('profile', 'change', 'statgrouped')):
        raise Http404

    today = datetime.date.today()
    month_1st_day = today.replace(day=1)

    data = request.GET or {
        'since': month_1st_day,
        'end': today,
        'group': 'contacts'
    }
    form = ByProvinceForm(data)
    if form.is_valid():
        data = form.cleaned_data

    date_range = [data['since'], data['end']]
    counter = collections.Counter()
    total = 0

    ads = Ad.objects.filter(created__range=date_range)
    if data['deal_type']:
        ads = ads.filter(deal_type=data['deal_type'])

    if data['group'] == 'photos':
        provincies = Region.get_provinces()
        for province in provincies:
            province.stats = {'with_photo': 0, 'total': 0}
            province.value = 0

        rows = ads.order_by('region__tree_path')\
            .values('region__tree_path', 'has_photos').order_by().annotate(count=Count('region__tree_path'))
        for row in rows:
            for province in provincies:
                if row['region__tree_path'] and row[
                        'region__tree_path'].startswith(
                            '%s.' % province.tree_path):
                    if row['has_photos']:
                        province.stats['with_photo'] += row['count']
                    province.stats['total'] += row['count']

        for province in provincies:
            province.value = '%s of %s' % (province.stats['with_photo'],
                                           province.stats['total'])
            if province.stats['total']:
                province.percent = province.stats[
                    'with_photo'] * 100 / province.stats['total']
                total += province.percent
        total = '%s %%' % (total / len(provincies))
    else:
        if data['group'] == 'contacts':
            for contacts_views, region_id, deal_type in ViewsCount.objects.filter(
                    date__range=date_range).values_list(
                        'contacts_views', 'basead__ad__region_id',
                        'basead__ad__deal_type'):
                if not data['deal_type'] or data['deal_type'] == deal_type:
                    counter[region_id] += contacts_views
        elif data['group'] == 'ads':
            counter = dict(
                ads.order_by('region').values_list('region').annotate(
                    count=Count('region')))

        # инициируем список областей и получаем список ID дочерних регионов
        provincies = Region.get_provinces()
        for province in provincies:
            province._children_ids = set(
                province.get_descendants(include_self=True).values_list(
                    'id', flat=True))
            province.value = 0

        # переносим данные по просмотрам из регионов в области
        for region_id, value in counter.items():
            for province in provincies:
                if region_id in province._children_ids:
                    province.value += value
                    total += value
                    break

        # подсчет процентов
        for province in provincies:
            if total:
                province.percent = float(province.value) * 100 / total

    return render(request, "admin/statistics_by_province.html", locals())
Ejemplo n.º 15
0
def set_region_from_url(sender, instance, **kwargs):
    from ad.models import Region
    instance.region = Region.get_region_and_params_from_url(instance.url).get('region')
Ejemplo n.º 16
0
def search(request, deal_type, property_type, regions_slug=None, show_result=None):
    region  = Region.get_region_from_slug(regions_slug, '' if request.subdomain == 'bank' else request.subdomain, request.subdomain_region)
    if not region:
        raise Http404
    
    # весь список объявлений с указанном типом объявления
    items_list = Ad.objects.filter(bank__isnull=False, is_published=True, deal_type__in=deal_type.split(',')).exclude(get_exclude_rules())\
        .prefetch_related('region','photos','user')

    # применяем фильтр по регионам
    items_list = items_list.filter(region__in=region.get_descendants(True))

    ad_property_types = convert_to_ad(property_type)
    items_list = items_list.filter(property_type__in=ad_property_types)
    
    min_price, max_price = get_price_range('%s_%s_%s_bank' % (deal_type, property_type, region.pk), items_list)
    
    # применяем фильтры поиска
    if len(request.GET) > 0:
        form = PropertySearchForm(request.GET) # A form bound to the POST data
        
        if form.is_valid():
            if not (len(request.GET)== 1 and 'property_type' in request.GET):
                show_result = True
            
            # currency rate
            curr_rate = 1
            if ('currency' in form.cleaned_data and form.cleaned_data['currency'] and form.cleaned_data['currency'] != 'UAH') and ((form.cleaned_data['price_from'] > 0) or (form.cleaned_data['price_to'] > 0)):
                from utils.currency import get_currency_rates
                curr_rate = get_currency_rates()[form.cleaned_data['currency']]
                
            if form.cleaned_data['price_from'] > 0:
                items_list = items_list.filter(price_uah__gte=form.cleaned_data['price_from'] * curr_rate)
            if form.cleaned_data['price_to'] > 0:
                items_list = items_list.filter(price_uah__lte=form.cleaned_data['price_to'] * curr_rate)
            
            if form.cleaned_data['rooms']:
                Q_rooms = Q()
                for room in form.cleaned_data['rooms']:
                    if room.find('+') > 0:
                        Q_rooms = Q_rooms | Q(rooms__gte=room[:-1])
                    else:
                        Q_rooms = Q_rooms | Q(rooms=room)
                items_list = items_list.filter(Q_rooms)
                
            if form.cleaned_data['property_commercial_type']:
                items_list = items_list.filter(property_commercial_type=form.cleaned_data['property_commercial_type'])
            
            if form.cleaned_data['with_image'] > 0:
                items_list = items_list.filter(has_photos=True)
                
            if form.cleaned_data['without_commission'] > 0:
                items_list = items_list.filter(without_commission=True)

            if form.cleaned_data['sort']:
                items_list = items_list.order_by(form.cleaned_data['sort'])
                
            # ключевые слова
            if form.cleaned_data['keywords'] != '':
                keywords = form.cleaned_data['keywords'].split(',')
                criterions = Q()
                for keyword in keywords:
                    keyword = keyword.strip()
                    selected_region = _check_region_subdomain(keyword)
                    if type(selected_region) == Region:
                        if selected_region != region:
                            kwargs = {'property_type': property_type}
                            region_slug = selected_region.get_region_slug()
                            if region_slug:
                                kwargs['regions_slug'] = region_slug
                            url = selected_region.get_host_url('bank-ad-search-result', host='bank', kwargs=kwargs)
                            return HttpResponsePermanentRedirect(url)
                    criterions.add(Q(description__icontains=keyword) | Q(address__icontains=keyword), Q.AND)
                items_list = items_list.filter(criterions)
            
    else:
        try:
            # в __init__ подготовка списка регионов для формы
            form = PropertySearchForm(request.GET)
        except Region.DoesNotExist: # не найден активный регион в выпадающем списке
            return redirect('..')
    
    if not show_result:
        items_list = items_list.filter(has_photos=True).order_by('-updated')
        items_list = items_list[:4]
    else:
        pass

    items_list = items_list.prefetch_related('photos')

    paginator = HandyPaginator(items_list, 10, request=request)

    seo_klass = SEO(current_language=settings.LANGUAGE_CODE)
    seo = seo_klass.get_seo(
        region=region,
        deal_type=deal_type,
        property_type=ad_property_types[0],
    )

    return render(request, 'bank/search.html', locals())
Ejemplo n.º 17
0
def export_ads_by_region_stats(request=None):
    if not request.user.has_perm("%s.%s_%s" %
                                 ('profile', 'change', 'statgrouped')):
        raise Http404

    regions = {region.id: region for region in Region.get_provinces()}
    regions_children = {
        region.id: set(region.get_children_ids())
        for region in regions.values()
    }
    managers = {manager.id: manager for manager in Manager.objects.all()}

    book = xlwt.Workbook(encoding='utf8')
    usertypes = (
        (1, u'частники', {
            'agencies__isnull': True
        }),
        (2, u'агентства', {
            'agencies__isnull': False
        }),
    )

    font = xlwt.Font()
    font.bold = True
    bold_style = xlwt.XFStyle()
    bold_style.font = font

    collect_data = collections.defaultdict(dict)

    import time
    start = time.time()

    now = datetime.datetime.now()
    periods = {
        'p1': [now - datetime.timedelta(days=7), now],
        'p2': [
            now - datetime.timedelta(days=1 * 30),
            now - datetime.timedelta(days=7)
        ],
        'p3': [
            now - datetime.timedelta(days=3 * 30),
            now - datetime.timedelta(days=1 * 30)
        ],
        'p4': [
            now - datetime.timedelta(days=6 * 30),
            now - datetime.timedelta(days=3 * 30)
        ],
        'p5': [
            now - datetime.timedelta(days=9 * 30),
            now - datetime.timedelta(days=6 * 30)
        ],
        'p6': [
            now - datetime.timedelta(days=12 * 30),
            now - datetime.timedelta(days=9 * 30)
        ],
        'p7': [
            now - datetime.timedelta(days=5 * 12 * 30),
            now - datetime.timedelta(days=12 * 30)
        ],
    }
    for period_id, date_range in periods.items():
        data = Ad.objects.filter(
            is_published=True, created__range=date_range).values(
                'user', 'deal_type',
                'region').annotate(count=Count('user')).order_by()
        for row in data:
            user = row['user']
            if user not in collect_data['ads']:
                collect_data['ads'][user] = collections.defaultdict(
                    collections.Counter)

            for region_id, children in regions_children.items():
                if row['region'] in children:
                    user_data = collect_data['ads'][user][region_id]
                    user_data[period_id] += row['count']
                    user_data[row['deal_type']] += row['count']

    # подсчет количество простров контактов в срезе юзер + регион объявления
    for period_id, date_range in periods.items():
        data = ViewsCount.objects.filter(
            basead__ad__is_published=True, date__range=date_range).values(
                'basead__ad__user', 'basead__ad__region',
                'basead__ad__deal_type').annotate(
                    count=Sum('contacts_views')).order_by()
        for row in data:
            user = row['basead__ad__user']
            if user not in collect_data['views']:
                collect_data['views'][user] = collections.defaultdict(
                    collections.Counter)

            for region_id, children in regions_children.items():
                if row['basead__ad__region'] in children:
                    user_data = collect_data['views'][user][region_id]
                    user_data[period_id] += row['count']
                    user_data[row['basead__ad__deal_type']] += row['count']

    print time.time() - start

    # заголовки таблицы
    user_columns = [
        u'User ID', u'Ссылка в админке', u'Пользователь', u'Город',
        u'Менеджер', u'Оборот', u'Область', u'', u'до 1 недели', u'1-4 нед.',
        u'1-3 мес.', u'3-6 мес.', u'6-9 мес.', u'9-12 мес.', u'более года', '',
        u'Продажа', u'Аренда', u'Посуточная', u'Новостройки'
    ]

    for key, group in collect_data.items():
        basename = {'ads': u'объявлений', 'views': u'просмотры'}[key]
        user_ids = set(group.keys())
        for usertype, name, user_filter in usertypes:
            print 'start sheet', time.time() - start
            sheet = book.add_sheet(u'%s (%s)' % (basename, name))
            sheet.col(1).width = 12000
            sheet.col(2).width = 12000
            sheet.col(3).width = 6000
            sheet.col(4).width = 6000

            [
                sheet.write(0, k, v, style=bold_style)
                for k, v in enumerate(user_columns)
            ]

            row_index = 1
            users = User.objects.filter(**user_filter).values(
                'id', 'city', 'email', 'first_name', 'last_name',
                'manager').order_by('-ads_count')
            print 'after user query', time.time() - start
            for user in users:
                if user['id'] not in user_ids:
                    continue

                name = " ".join(
                    [user['email'], user['first_name'], user['last_name']])
                # entranses = Stat.objects.filter(user=user['id'], date=datetime.datetime.now() - datetime.timedelta(days=30)).values('user').aggregate(entrances=Sum('entrances'))['entrances']
                revenue = Transaction.objects.filter(
                    user_id=user['id'], amount__gt=0).values('user').aggregate(
                        amount=Sum('amount'))['amount']
                manager = unicode(managers.get(user['manager'], ''))
                user_data = [
                    user['id'],
                    'http://mesto.ua/admin/custom_user/user/?id=%s' %
                    user['id'], name, user['city'], manager, revenue
                ]

                for region_id, stats in group[user['id']].items():
                    row = user_data +  \
                          [regions[region_id].name.replace(u' область', '')] + [u''] + \
                          [stats['p%s' % period] for period in xrange(1, 8)] + [u''] + \
                          [stats[deal_type] for deal_type in ['sale', 'rent', 'rent_daily', 'newhomes']]

                    [sheet.write(row_index, k, v) for k, v in enumerate(row)]
                    row_index += 1
            print 'end sheet', time.time() - start

    filename = 'export_ads_by_region_stats%s.xls' % datetime.datetime.now(
    ).strftime('%Y-%m-%d_%H-%M')
    book.save(filename)

    buffer_io = StringIO.StringIO()
    book.save(buffer_io)

    response = HttpResponse(buffer_io.getvalue(),
                            content_type='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=%s' % filename
    return response