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())
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())
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
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
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')
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())
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())
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())
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
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)
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())
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)
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)
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())
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')
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())
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