952 lines
55 KiB
Python
952 lines
55 KiB
Python
# -*- coding: utf-8 -*-
|
||
from django.core.exceptions import ObjectDoesNotExist
|
||
from django.shortcuts import render, redirect
|
||
from django.http import HttpRequest, HttpResponse
|
||
from django.template.loader import render_to_string
|
||
from django.utils import timezone
|
||
from oknardia.settings import *
|
||
from oknardia.models import PVCprofiles, Seria_Info, Win_MountDim, Building_Info, MerchantBrand
|
||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
|
||
from web.add_func import normalize, get_rating_set_for_stars, get_flaps_for_big_pictures, make_flap_mini_pictures
|
||
import django.utils.dateformat
|
||
import time
|
||
import json
|
||
import random
|
||
import re
|
||
import os
|
||
import math
|
||
import pytils
|
||
|
||
|
||
def catalog_root(request: HttpRequest) -> HttpResponse:
|
||
""" Корневая страница каталога
|
||
|
||
ИДЕЯ: со временем нужно сделать функционал показа случайных картинок в каждый раздел (чтоб поисковики фигели)
|
||
|
||
:param request: HttpRequest -- входящий http-запрос
|
||
:return response: HttpResponse -- исходящий http-ответ
|
||
"""
|
||
time_start = time.time()
|
||
# получаем из cookies последние визиты клиента
|
||
to_template = {
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)}
|
||
response = render(request, "catalog/catalog_root.html", to_template)
|
||
return response
|
||
|
||
|
||
def catalog_profile(request: HttpRequest) -> HttpResponse:
|
||
"""
|
||
КАТАЛОГ ПРОФИЛЕЙ: страница со списком производителей и моделей (марками) профилей
|
||
|
||
:param request: HttpRequest -- входящий http-запрос
|
||
:return response: HttpResponse -- исходящий http-ответ
|
||
"""
|
||
time_start = time.time()
|
||
q_profile = PVCprofiles.objects.raw('SELECT'
|
||
' oknardia_pvcprofiles.id,'
|
||
' oknardia_pvcprofiles.sProfileName,'
|
||
' oknardia_pvcprofiles.sProfileBriefDescription,'
|
||
' oknardia_pvcprofiles.sProfileManufacturer,'
|
||
' oknardia_catalog2profile.sCatalogCardType,'
|
||
' oknardia_blogposts.sPostContent,'
|
||
' oknardia_blogposts.sPostHeader,'
|
||
'oknardia_pvcprofiles.dProfileModify,'
|
||
'MAX(oknardia_blogposts.dPostDataModify) AS lastBlog '
|
||
'FROM oknardia_catalog2profile'
|
||
' RIGHT OUTER JOIN oknardia_pvcprofiles'
|
||
' ON oknardia_catalog2profile.kProfile_id = oknardia_pvcprofiles.id'
|
||
' LEFT OUTER JOIN oknardia_blogposts'
|
||
' ON oknardia_catalog2profile.kBlogCatalog_id = oknardia_blogposts.id '
|
||
'GROUP BY oknardia_catalog2profile.sCatalogCardType,'
|
||
' oknardia_pvcprofiles.sProfileName,'
|
||
' oknardia_pvcprofiles.id,'
|
||
' oknardia_pvcprofiles.sProfileBriefDescription,'
|
||
' oknardia_pvcprofiles.sProfileManufacturer,'
|
||
' oknardia_blogposts.sPostHeader,'
|
||
' oknardia_blogposts.sPostContent,'
|
||
' oknardia_pvcprofiles.dProfileModify '
|
||
'ORDER BY oknardia_pvcprofiles.sProfileManufacturer,'
|
||
' oknardia_pvcprofiles.sProfileBriefDescription;')
|
||
to_template = {'CATALOG_PROFILE_NUM': pytils.numeral.get_plural(len(list(q_profile)), "профиль,профиля,профилей")}
|
||
list_profile_manufactures = []
|
||
tmp_profile_manufacture = ""
|
||
last_update = None
|
||
for i in q_profile:
|
||
if last_update is None:
|
||
last_update = i.dProfileModify
|
||
if last_update < i.dProfileModify:
|
||
last_update = i.dProfileModify
|
||
# if (i.lastBlog is not None) and (last_update < i.lastBlog):
|
||
# last_update = i.lastBlog
|
||
if tmp_profile_manufacture != i.sProfileManufacturer:
|
||
tmp_profile_manufacture = i.sProfileManufacturer
|
||
list_profile_manufactures.append({
|
||
"PROF_MAN_ID": i.id,
|
||
"PROF_MAN": i.sProfileManufacturer,
|
||
"PROF_MAN_T": pytils.translit.slugify(i.sProfileManufacturer).lower(),
|
||
"PROF_MAN_LIST": [{
|
||
"PROF_NAME_ID": i.id,
|
||
"PROF_NAME": i.sProfileBriefDescription,
|
||
"PROF_NAME_T": pytils.translit.slugify(i.sProfileName).lower(),
|
||
}]
|
||
})
|
||
# print("===", i.sProfileManufacturer, ">>> >>> >>>", Rus2Url(i.sProfileManufacturer))
|
||
elif len(list_profile_manufactures) == 0:
|
||
# Какая-то фигня. Похоже "пустой" производитель профиля (пустая строка). Ну его нафиг.
|
||
continue
|
||
else:
|
||
list_profile_manufactures[-1]["PROF_MAN_LIST"].append({
|
||
"PROF_NAME_ID": i.id,
|
||
"PROF_NAME": i.sProfileBriefDescription,
|
||
"PROF_NAME_T": pytils.translit.slugify(i.sProfileName).lower(),
|
||
})
|
||
# print(\"--- ---", i.sProfileBriefDescription, ">>>", Rus2Url(i.sProfileBriefDescription))
|
||
to_template.update({
|
||
'CATALOG_PROFILE_MAN1_NAME2': list_profile_manufactures,
|
||
'CATALOG_MANUFACT_NUM': len(list_profile_manufactures),
|
||
'CATALOG_MANUFACT_NUM_W':
|
||
pytils.numeral.sum_string(len(list_profile_manufactures), pytils.numeral.MALE, ("производитель",
|
||
"производителя",
|
||
"производителей")),
|
||
'CATALOG_LAST_UPDATE': last_update,
|
||
'CATALOG_LAST_UPDATE_W': pytils.dt.distance_of_time_in_words(time.mktime(last_update.timetuple()), accuracy=2),
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)
|
||
})
|
||
return render(request, "catalog/catalog_of_profiles.html", to_template)
|
||
|
||
|
||
def catalog_profile_model(request: HttpRequest, manufacture_id: int, manufacture_name: str,
|
||
model_id: id, model_name: str) -> HttpResponse:
|
||
"""
|
||
КАТАЛОГ ПРОФИЛЕЙ: страница с описанием марки профиля
|
||
|
||
:param request: HttpRequest -- входящий http-запрос
|
||
:param manufacture_id: id профиля. Предполагается, что это первый id при сортировке по sProfileBriefDescription
|
||
:param manufacture_name: название производителя (транслитерированное pytils.translit.slugify())
|
||
:param model_id: id модели (марки) профиля
|
||
:param model_name: модель (марка) профиля (транслитерированное pytils.translit.slugify(sProfileName))
|
||
:return response: HttpResponse -- исходящий http-ответ
|
||
"""
|
||
time_start = time.time()
|
||
manufacture_id = int(manufacture_id)
|
||
model_id = int(model_id)
|
||
q_pvc_by_id = PVCprofiles.objects.get(id=model_id)
|
||
if pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer) != manufacture_name \
|
||
or pytils.translit.slugify(q_pvc_by_id.sProfileName) != model_name \
|
||
or manufacture_id != model_id:
|
||
return redirect(f"/catalog/profile/{model_id}-{pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)}/"
|
||
f"{model_id}-{pytils.translit.slugify(q_pvc_by_id.sProfileName)}")
|
||
to_template = {"CATALOG_MODEL": q_pvc_by_id,
|
||
"CATALOG_MAN2URL": manufacture_name,
|
||
"CATALOG_URL": f"{manufacture_id}-{manufacture_name}",
|
||
"CATALOG_URL2": f"{manufacture_id}-{manufacture_name}/{model_id}-{model_name}",
|
||
"PROFILE_RATING_STARS": get_rating_set_for_stars(q_pvc_by_id.fProfileRating)}
|
||
try:
|
||
got_json = json.loads(q_pvc_by_id.sProfileDescription)
|
||
# раскрашиваем кружочки рейтинга напротив характеристик профиля
|
||
if KEY_RATING in got_json:
|
||
# RatingReal = True # Рейтинг реальный (профиль представлен в ценовых предложениях)
|
||
# кружочки зелёные
|
||
rating = got_json[KEY_RATING]
|
||
color = int(255 - rating[RANK_PVCP_CAMERAS_NUM_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_CAMERAS_COLOR": f"{color},255,{color}"})
|
||
color = int(255 - rating[RANK_PVCP_SEALS_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_SEALS_COLOR": f"{color},255,{color}"})
|
||
color = int(255 - rating[RANK_PVCP_THICKNESS_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_THICKNESS_COLOR": f"{color},255,{color}"})
|
||
color = int(255 - rating[RANK_PVCP_G_THICKNESS_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_G_THICKNESS_COLOR": f"{color},255,{color}"})
|
||
color = int(255 - rating[RANK_PVCP_RABBET_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_RABBET_COLOR": f"{color},255,{color}"})
|
||
color = int(255 - rating[RANK_PVCP_HEAT_TRANSFER_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_HEAT_TRANSFER_COLOR": f"{color},255,{color}"})
|
||
color = int(255 - rating[RANK_PVCP_SOUNDPROOFING_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_SOUNDPROOFING_COLOR": f"{color},255,{color}"})
|
||
color = int(255 - rating[RANK_PVCP_HEIGHT_NAME] * 255)
|
||
to_template.update({"RANK_PVCP_HEIGHT_COLOR": f"{color},255,{color}"})
|
||
elif KEY_RATING_VIRTUAL in got_json:
|
||
# RatingReal = False # Рейтинг виртуальный (профиль представлен в ценовых предложениях)
|
||
# кружочки серые
|
||
rating = got_json[KEY_RATING_VIRTUAL]
|
||
color = int(255 - rating[RANK_PVCP_CAMERAS_NUM_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_CAMERAS_COLOR": f"{color},{color},{color}"})
|
||
color = int(255 - rating[RANK_PVCP_SEALS_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_SEALS_COLOR": f"{color},{color},{color}"})
|
||
color = int(255 - rating[RANK_PVCP_THICKNESS_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_THICKNESS_COLOR": f"{color},{color},{color}"})
|
||
color = int(255 - rating[RANK_PVCP_G_THICKNESS_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_G_THICKNESS_COLOR": f"{color},{color},{color}"})
|
||
color = int(255 - rating[RANK_PVCP_RABBET_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_RABBET_COLOR": f"{color},{color},{color}"})
|
||
color = int(255 - rating[RANK_PVCP_HEAT_TRANSFER_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_HEAT_TRANSFER_COLOR": f"{color},{color},{color}"})
|
||
color = int(255 - rating[RANK_PVCP_SOUNDPROOFING_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_SOUNDPROOFING_COLOR": f"{color},{color},{color}"})
|
||
color = int(255 - rating[RANK_PVCP_HEIGHT_NAME] * 64)
|
||
to_template.update({"RANK_PVCP_HEIGHT_COLOR": f"{color},{color},{color}"})
|
||
else:
|
||
pass
|
||
if KEY_HTML in got_json:
|
||
to_template.update({"EXTRA_INFO": got_json[KEY_HTML]})
|
||
except (TypeError, ValueError, KeyError):
|
||
pass
|
||
list_other = []
|
||
for i in q_pvc_by_id.sProfileOther.split(";"):
|
||
j = i.find(":")
|
||
list_other.append(u"<b>" + i[:j + 1] + u"</b>" + i[j + 1:])
|
||
to_template.update({"LIST_OTHER": list_other})
|
||
q_merchant = PVCprofiles.objects.raw(f"SELECT"
|
||
f" COUNT(oknardia_priceoffer.id) AS offers_by_merchant,"
|
||
f" oknardia_merchantbrand.sMerchantName,"
|
||
f" oknardia_merchantbrand.pMerchantLogo,"
|
||
f" oknardia_merchantbrand.id "
|
||
f"FROM oknardia_priceoffer"
|
||
f" INNER JOIN oknardia_setkit"
|
||
f" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
|
||
f" INNER JOIN oknardia_pvcprofiles"
|
||
f" ON oknardia_setkit.kSet2PVCprofiles_id = oknardia_pvcprofiles.id"
|
||
f" INNER JOIN oknardia_ouruser"
|
||
f" ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id"
|
||
f" INNER JOIN oknardia_merchantoffice"
|
||
f" ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id"
|
||
f" INNER JOIN oknardia_merchantbrand"
|
||
f" ON oknardia_merchantoffice.kMerchantName_id = oknardia_merchantbrand.id "
|
||
f"WHERE oknardia_pvcprofiles.id = {model_id} "
|
||
f"GROUP BY oknardia_merchantbrand.sMerchantName,"
|
||
f" oknardia_merchantbrand.pMerchantLogo,"
|
||
f" oknardia_merchantbrand.id "
|
||
f"ORDER BY offers_by_merchant DESC;")
|
||
list_merchant = []
|
||
for i in q_merchant:
|
||
list_merchant.append({
|
||
"MERCHANT_ID": i.id,
|
||
"MERCHANT_NAME": i.sMerchantName,
|
||
"MERCHANT_NAME_T": pytils.translit.slugify(i.sMerchantName),
|
||
"MERCHANT_LOGO_URL": i.pMerchantLogo,
|
||
"MERCHANT_OFFERS": i.offers_by_merchant,
|
||
})
|
||
to_template.update({'MERCHANTS': list_merchant})
|
||
q_profiles = PVCprofiles.objects.raw(f"SELECT oknardia_pvcprofiles.id,"
|
||
f" oknardia_pvcprofiles.fProfileRating,"
|
||
f" oknardia_pvcprofiles.sProfileBriefDescription,"
|
||
f" oknardia_pvcprofiles.sProfileName "
|
||
f"FROM oknardia_pvcprofiles "
|
||
f"WHERE oknardia_pvcprofiles.sProfileManufacturer ="
|
||
f" '{q_pvc_by_id.sProfileManufacturer}' "
|
||
f"ORDER BY oknardia_pvcprofiles.fProfileRating;")
|
||
list_profiles = []
|
||
for i in q_profiles:
|
||
if i.id != model_id:
|
||
list_profiles.append({
|
||
"PROFILE_NAME": i.sProfileBriefDescription,
|
||
"PROFILE_ID": i.id,
|
||
"PROFILE_URL": pytils.translit.slugify(i.sProfileName).lower(),
|
||
"PROFILE_RATING": i.fProfileRating,
|
||
"PROFILE_RATING_STARS": get_rating_set_for_stars(i.fProfileRating),
|
||
})
|
||
to_template.update({'PROFILES': list_profiles})
|
||
q_profiles_detail = PVCprofiles.objects.raw(f"SELECT"
|
||
f" oknardia_blogposts.*,"
|
||
f" oknardia_pvcprofiles.id,"
|
||
f" oknardia_catalog2profile.sCatalogCardType,"
|
||
f" oknardia_blogposts.iCatalogSort "
|
||
f"FROM oknardia_catalog2profile"
|
||
f" INNER JOIN oknardia_blogposts"
|
||
f" ON oknardia_catalog2profile.kBlogCatalog_id=oknardia_blogposts.id"
|
||
f" INNER JOIN oknardia_pvcprofiles"
|
||
f" ON oknardia_catalog2profile.kProfile_id=oknardia_pvcprofiles.id "
|
||
f"WHERE oknardia_pvcprofiles.id = {model_id} "
|
||
f"AND oknardia_catalog2profile.sCatalogCardType ="
|
||
f" {CATALOG_RECORD_FOR_PROFILE_MODEL} "
|
||
f"ORDER BY oknardia_blogposts.iCatalogSort;")
|
||
list_profiles_detail = list(q_profiles_detail)
|
||
to_template.update({'PROFILE_DETAIL': list_profiles_detail})
|
||
list_img_for_blog = []
|
||
for i in list_profiles_detail:
|
||
if i.sImgForBlogSocial != "":
|
||
list_img_for_blog.append(i.sImgForBlogSocial)
|
||
if len(list_profiles_detail) > 0:
|
||
random.shuffle(list_img_for_blog)
|
||
to_template.update({'IMG_FOR_BLOG': list_img_for_blog[0]})
|
||
to_template.update({'PUB_DAT': q_pvc_by_id.dProfileModify})
|
||
if len(list_profiles_detail) > 0:
|
||
pub_data = sorted(list_profiles_detail, key=lambda item: item.dPostDataModify)[0].dPostDataModify
|
||
if pub_data.replace(tzinfo=None) < q_pvc_by_id.dProfileModify.replace(tzinfo=None):
|
||
to_template.update({'PUB_DAT': pub_data})
|
||
to_template.update({
|
||
# получаем последние визиты клиента через куки
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
# получаем последние визиты всех посетителей из базы
|
||
# id2log, log_visit = get_last_all_user_visit_list()
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)
|
||
})
|
||
return render(request, "catalog/catalog_of_profiles_model.html", to_template)
|
||
|
||
|
||
def catalog_profile_manufacture(request: HttpRequest, manufacture_id: int, manufacture_name: str) -> HttpResponse:
|
||
"""
|
||
КАТАЛОГ ПРОФИЛЕЙ: страница с описанием производителя профилей и списком марки производимых им профилей
|
||
|
||
:param request: HttpRequest -- входящий http-запрос
|
||
:param manufacture_id: id профиля. Предполагается, что это первый id при сортировке по sProfileBriefDescription
|
||
:param manufacture_name: название производителя (транслитерированное pytils.translit.slugify())
|
||
:return response: HttpResponse -- исходящий http-ответ
|
||
"""
|
||
time_start = time.time()
|
||
manufacture_id = int(manufacture_id)
|
||
q_pvc_by_id = PVCprofiles.objects.get(id=manufacture_id)
|
||
if pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer) != manufacture_name:
|
||
return redirect(f'/catalog/profile/{manufacture_id}-'
|
||
f'{pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)}')
|
||
else:
|
||
q_pvc_by_id = PVCprofiles.objects.order_by('id') \
|
||
.filter(sProfileManufacturer=q_pvc_by_id.sProfileManufacturer).first()
|
||
if q_pvc_by_id.id != manufacture_id:
|
||
return redirect(f'/catalog/profile/{q_pvc_by_id.id}-'
|
||
f'{pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)}')
|
||
to_template = {'CATALOG_MANUFACT': q_pvc_by_id.sProfileManufacturer,
|
||
'CATALOG_MAN2URL': manufacture_name,
|
||
'CATALOG_URL': f"{manufacture_id}-{manufacture_name}"}
|
||
try:
|
||
# получаем информацию о производителе (статью из блога)
|
||
manufacture_description = list(PVCprofiles.objects.raw(
|
||
f"SELECT "
|
||
f" oknardia_blogposts.* "
|
||
f"FROM oknardia_catalog2profile"
|
||
f" RIGHT OUTER JOIN oknardia_pvcprofiles"
|
||
f" ON oknardia_catalog2profile.kProfile_id = oknardia_pvcprofiles.id"
|
||
f" LEFT OUTER JOIN oknardia_blogposts"
|
||
f" ON oknardia_catalog2profile.kBlogCatalog_id = oknardia_blogposts.id "
|
||
f"WHERE oknardia_catalog2profile.sCatalogCardType = {CATALOG_RECORD_FOR_PROFILE_MANUFACTURER} "
|
||
f" AND oknardia_pvcprofiles.sProfileManufacturer = '{q_pvc_by_id.sProfileManufacturer}'"
|
||
f" AND oknardia_blogposts.bCatalog IS TRUE "
|
||
f"GROUP BY oknardia_blogposts.bCatalog "
|
||
f"LIMIT 1;"
|
||
))[0]
|
||
to_template.update({'PUB_DAT': manufacture_description.dPostDataModify})
|
||
if PATH_FOR_IMG_BLOG in manufacture_description.sImgForBlogSocial:
|
||
to_template.update({'IMG_FOR_BLOG': manufacture_description.sImgForBlogSocial})
|
||
to_template.update({'HEADER': manufacture_description.sPostHeader,
|
||
'CONTENT': re.sub(r'<cut[\s\S]*>', '', manufacture_description.sPostContent,
|
||
0, re.IGNORECASE)})
|
||
to_template.update({'TIZER': re.sub(r'<script[\s\S]*?</script>|<style[\s\S]*?</style>|<iframe[\s\S]*?</iframe>',
|
||
'', to_template["CONTENT"], 0, re.IGNORECASE)})
|
||
except (ObjectDoesNotExist, IndexError, TypeError, KeyError,):
|
||
pass
|
||
q_profiles = PVCprofiles.objects.raw(
|
||
f"SELECT oknardia_pvcprofiles.id,"
|
||
f" oknardia_pvcprofiles.fProfileRating,"
|
||
f" oknardia_pvcprofiles.sProfileBriefDescription,"
|
||
f" oknardia_pvcprofiles.sProfileName "
|
||
f"FROM oknardia_pvcprofiles "
|
||
f"WHERE oknardia_pvcprofiles.sProfileManufacturer = '{q_pvc_by_id.sProfileManufacturer}' "
|
||
f"ORDER BY oknardia_pvcprofiles.fProfileRating;"
|
||
)
|
||
list_profiles = []
|
||
for i in q_profiles:
|
||
list_profiles.append({
|
||
"PROFILE_NAME": i.sProfileBriefDescription,
|
||
"PROFILE_ID": i.id,
|
||
"PROFILE_URL": pytils.translit.slugify(i.sProfileName).lower(),
|
||
"PROFILE_RATING": i.fProfileRating,
|
||
"PROFILE_RATING_STARS": get_rating_set_for_stars(i.fProfileRating),
|
||
})
|
||
to_template.update({'PROFILES': list_profiles})
|
||
try:
|
||
q_share_of_offers = list(PVCprofiles.objects.raw(
|
||
f"SELECT"
|
||
f" 1 AS id,"
|
||
f" SUM(Q1.offers_by_model) AS offers_by_maufacture,"
|
||
f" Q2.tatal_offers-SUM(Q1.offers_by_model) AS offers_other "
|
||
f"FROM (SELECT COUNT(oknardia_priceoffer.id) AS offers_by_model"
|
||
f" FROM oknardia_priceoffer"
|
||
f" LEFT OUTER JOIN oknardia_setkit"
|
||
f" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
|
||
f" RIGHT OUTER JOIN oknardia_pvcprofiles"
|
||
f" ON oknardia_setkit.kSet2PVCprofiles_id = oknardia_pvcprofiles.id"
|
||
f" WHERE oknardia_pvcprofiles.sProfileManufacturer = '{q_pvc_by_id.sProfileManufacturer}') Q1,"
|
||
f" (SELECT COUNT(oknardia_priceoffer.id) AS tatal_offers"
|
||
f" FROM oknardia_priceoffer) AS Q2 "
|
||
f"LIMIT 1;"
|
||
))[0]
|
||
to_template.update({
|
||
'OFFERS_BY_MAUFACTURE': q_share_of_offers.offers_by_maufacture,
|
||
'OFFERS_OTHER': q_share_of_offers.offers_other,
|
||
'OFFERS_ANGLE': 90 + 180 * normalize(q_share_of_offers.offers_by_maufacture,
|
||
q_share_of_offers.offers_other + q_share_of_offers.offers_by_maufacture)
|
||
})
|
||
if q_share_of_offers is not None and q_share_of_offers.offers_by_maufacture != 0:
|
||
q_merchant = PVCprofiles.objects.raw(
|
||
f"SELECT"
|
||
f" COUNT(oknardia_priceoffer.id) AS offers_by_merchant,"
|
||
f" oknardia_merchantbrand.sMerchantName,"
|
||
f" oknardia_merchantbrand.pMerchantLogo,"
|
||
f" oknardia_merchantbrand.id "
|
||
f"FROM oknardia_priceoffer"
|
||
f" INNER JOIN oknardia_setkit"
|
||
f" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
|
||
f" INNER JOIN oknardia_pvcprofiles"
|
||
f" ON oknardia_setkit.kSet2PVCprofiles_id = oknardia_pvcprofiles.id"
|
||
f" INNER JOIN oknardia_ouruser"
|
||
f" ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id"
|
||
f" INNER JOIN oknardia_merchantoffice"
|
||
f" ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id"
|
||
f" INNER JOIN oknardia_merchantbrand"
|
||
f" ON oknardia_merchantoffice.kMerchantName_id = oknardia_merchantbrand.id "
|
||
f"WHERE oknardia_pvcprofiles.sProfileManufacturer = '{q_pvc_by_id.sProfileManufacturer}' "
|
||
f"GROUP BY oknardia_merchantbrand.sMerchantName,"
|
||
f" oknardia_merchantbrand.pMerchantLogo,"
|
||
f" oknardia_merchantbrand.id "
|
||
f"ORDER BY offers_by_merchant DESC;"
|
||
)
|
||
list_merchant = []
|
||
for i in q_merchant:
|
||
list_merchant.append({
|
||
"MERCHANT_ID": i.id,
|
||
"MERCHANT_NAME": i.sMerchantName,
|
||
"MERCHANT_NAME_T": pytils.translit.slugify(i.sMerchantName),
|
||
"MERCHANT_LOGO_URL": i.pMerchantLogo,
|
||
"MERCHANT_OFFERS": i.offers_by_merchant
|
||
})
|
||
to_template.update({'MERCHANTS': list_merchant})
|
||
except (ObjectDoesNotExist, IndexError, TypeError): # вообще-то, запрос q_share_of_offers всегда что-то вернёт,
|
||
pass # но на всякий случай
|
||
to_template.update({
|
||
# получаем последние визиты клиента через куки
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
# получаем последние визиты всех посетителей из базы
|
||
# id2log, log_visit = get_last_all_user_visit_list()
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)
|
||
})
|
||
return render(request, "catalog/catalog_of_profiles_manufacture.html", to_template)
|
||
|
||
|
||
# Каталог типовый серий зданий (пока переадресация)
|
||
def catalog_seria(request: HttpRequest) -> HttpResponse:
|
||
"""
|
||
КАТАЛОГ ТИПОВЫЙ СЕРИЙ: страница со всеми сериями зданий в базе окнардии
|
||
|
||
:param request: HttpRequest -- входящий http-запрос
|
||
:return response: HttpResponse -- исходящий http-ответ
|
||
"""
|
||
time_start = time.time()
|
||
try:
|
||
q_seria = Seria_Info.objects.raw('SELECT'
|
||
' oknardia_seria_info.id,'
|
||
' oknardia_seria_info.sURL2IMG,'
|
||
' oknardia_seria_info.sName '
|
||
'FROM oknardia_seria_info '
|
||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||
'ORDER BY oknardia_seria_info.sName;')
|
||
list_seria = []
|
||
for i in q_seria:
|
||
list_seria.append({
|
||
"ID": i.id,
|
||
"URL": i.sURL2IMG,
|
||
"NAME": i.sName,
|
||
"NAME_T": pytils.translit.slugify(i.sName)
|
||
})
|
||
to_template = {'SERIAS': list_seria}
|
||
except (ObjectDoesNotExist,):
|
||
to_template = {}
|
||
to_template.update({
|
||
# получаем последние визиты клиента через куки
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
# получаем последние визиты всех посетителей из базы
|
||
# id2log, log_visit = get_last_all_user_visit_list()
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)
|
||
})
|
||
return render(request, "catalog/catalog_seria.html", to_template)
|
||
|
||
|
||
def catalog_seria_info(request: HttpRequest, seria_name_translit: str = "II-49", seria_id: int = 12) -> HttpResponse:
|
||
"""
|
||
КАТАЛОГ ТИПОВЫЙ СЕРИЙ: страница детальной информацией по серии зданий
|
||
|
||
:param request: HttpRequest -- входящий http-запрос
|
||
:param seria_name_translit: str -- имя серии здания (транслитерированное pytils.translit.slugify())
|
||
:param seria_id: int -- id серии
|
||
:return response: HttpResponse -- исходящий http-ответ
|
||
"""
|
||
time_start = time.time()
|
||
msg = ""
|
||
try:
|
||
seria_id = int(seria_id)
|
||
q_seria = Seria_Info.objects.get(id=seria_id)
|
||
if q_seria.id != q_seria.kRoot_id or seria_name_translit != pytils.translit.slugify(q_seria.sName):
|
||
return redirect(f"/catalog/seria/{pytils.translit.slugify(q_seria.sName)}/all{seria_id}")
|
||
except(ObjectDoesNotExist, ValueError,):
|
||
return redirect("/catalog/")
|
||
# если есть "облегченный" шаблон с частичным пре-рендером, то используем его.
|
||
light_template = f"{PATH_FOR_SERIA_INFO_HTML_INCLUDE}{str(seria_id)}_id.html"
|
||
light_template_w_path = f"{TEMPLATES[0]['DIRS'][0]}/{light_template}"
|
||
# print(f"{TEMPLATES[0]['DIRS'][0]}/{light_template}")
|
||
# print(light_template_w_path)
|
||
if os.path.isfile(light_template_w_path):
|
||
is_hard_template = False
|
||
else:
|
||
is_hard_template = True
|
||
to_template = {}
|
||
# получаем проемы использующиеся в данной серии домов
|
||
q_windows_in_seria = Win_MountDim.objects.raw(
|
||
f"SELECT DISTINCT"
|
||
f" oknardia_win_mountdim.iWinWidth, oknardia_win_mountdim.iWinHight,"
|
||
f" oknardia_win_mountdim.sDescripion, oknardia_win_mountdim.bIsDoor,"
|
||
f" oknardia_win_mountdim.bIsNearDoor, oknardia_win_mountdim.sFlapConfig,"
|
||
f" oknardia_win_mountdim.iWinDepth, oknardia_win_mountdim.id,"
|
||
f" 1 AS iQuantity "
|
||
f"FROM oknardia_mountdim2apartment"
|
||
f" INNER JOIN oknardia_win_mountdim"
|
||
f" ON oknardia_mountdim2apartment.kMountDim_id = oknardia_win_mountdim.id"
|
||
f" INNER JOIN oknardia_apartment_type"
|
||
f" ON oknardia_mountdim2apartment.kApartment_id = oknardia_apartment_type.id "
|
||
f"WHERE oknardia_apartment_type.kSeria_id = {seria_id}"
|
||
f" ORDER BY oknardia_win_mountdim.bIsNearDoor DESC,"
|
||
f" oknardia_win_mountdim.bIsDoor DESC,"
|
||
f" oknardia_win_mountdim.iWinWidth,"
|
||
f" oknardia_win_mountdim.iWinHight DESC;")
|
||
if is_hard_template:
|
||
# Получаем данные для отрисовки больших картинок с проёмами и передаём в "тяжёлый" шаблон
|
||
to_template.update(get_flaps_for_big_pictures(q_windows_in_seria))
|
||
# формируем строку для включения в SQL-запрос вида "(2,8,16,46,1)"
|
||
str_for_sql_in = "("
|
||
for count in q_windows_in_seria:
|
||
str_for_sql_in += str(count.id) + ","
|
||
str_for_sql_in = str_for_sql_in[:-1] + ")"
|
||
# print StringForSqlIN
|
||
# Получаем данные для таблички Окон по типам квартирах в серии дома
|
||
# " IFNULL(oknardia_mountdim2apartment.iQuantity, 0) AS iQuantity," \
|
||
# tStart2 = time.time() # замер времени
|
||
q_win_in_apartment_in_seria = Win_MountDim.objects.raw(
|
||
f"SELECT"
|
||
f" oknardia_win_mountdim.id,"
|
||
f" oknardia_apartment_type.sNameApartment,"
|
||
f" oknardia_win_mountdim.iWinWidth,"
|
||
f" oknardia_win_mountdim.iWinHight,"
|
||
f" oknardia_apartment_type.id AS id_apart,"
|
||
f" IFNULL(oknardia_mountdim2apartment.iQuantity, 0) AS iQuantity,"
|
||
f" COUNT(oknardia_priceoffer.id) AS NumOffers "
|
||
f"FROM oknardia_apartment_type"
|
||
f" INNER JOIN oknardia_win_mountdim"
|
||
f" LEFT OUTER JOIN oknardia_mountdim2apartment"
|
||
f" ON oknardia_mountdim2apartment.kMountDim_id = oknardia_win_mountdim.id"
|
||
f" AND oknardia_mountdim2apartment.kApartment_id = oknardia_apartment_type.id"
|
||
f" LEFT OUTER JOIN oknardia_priceoffer"
|
||
f" ON oknardia_priceoffer.kOffer2MountDim_id = oknardia_win_mountdim.id"
|
||
f" LEFT OUTER JOIN oknardia_ouruser"
|
||
f" ON oknardia_ouruser.id = oknardia_priceoffer.kOfferFromUser_id "
|
||
f"WHERE oknardia_apartment_type.kSeria_id = {seria_id} "
|
||
f"AND oknardia_win_mountdim.id IN {str_for_sql_in} "
|
||
f"GROUP BY oknardia_apartment_type.id,"
|
||
f" oknardia_apartment_type.sNameApartment,"
|
||
f" oknardia_win_mountdim.id,"
|
||
f" oknardia_mountdim2apartment.iQuantity "
|
||
f"ORDER BY oknardia_apartment_type.iSort,"
|
||
f" oknardia_win_mountdim.bIsNearDoor DESC,"
|
||
f" oknardia_win_mountdim.bIsDoor DESC,"
|
||
f" oknardia_win_mountdim.iWinWidth,"
|
||
f" oknardia_win_mountdim.iWinHight DESC;")
|
||
list_win_in_seria = list(q_windows_in_seria)
|
||
total_column = len(list_win_in_seria) - 1
|
||
count_column = 0
|
||
min_offer_in_row = 1000000000
|
||
table_of_win_in_seria_by_apartmment = []
|
||
row_for_table = []
|
||
offer_and_merchant_per_win = [
|
||
{
|
||
"WIN_OFFER": 0,
|
||
"WIN_MERCHANT": 0,
|
||
"WIN_W": list_win_in_seria[i].iWinWidth,
|
||
"WIN_H": list_win_in_seria[i].iWinHight,
|
||
"WIN_ID": list_win_in_seria[i].id
|
||
} for i in range(total_column + 1)]
|
||
for count in q_win_in_apartment_in_seria:
|
||
if count.iQuantity != 0:
|
||
row_for_table.append({
|
||
"WIN_NUM": [chr(65 + count_column)],
|
||
"WIN_Q": count.iQuantity,
|
||
"WIN_ID": count.id,
|
||
"WIN_WIDTH": list_win_in_seria[count_column].iWinWidth,
|
||
"WIN_HEIGHT": list_win_in_seria[count_column].iWinHight,
|
||
"WIN_DESCRIPTION": list_win_in_seria[count_column].sDescripion,
|
||
"WIN_FLAPCFG": list_win_in_seria[count_column].sFlapConfig
|
||
})
|
||
if min_offer_in_row > count.NumOffers:
|
||
min_offer_in_row = count.NumOffers
|
||
if offer_and_merchant_per_win[count_column]["WIN_OFFER"] < count.NumOffers:
|
||
offer_and_merchant_per_win[count_column]["WIN_OFFER"] = count.NumOffers
|
||
else:
|
||
row_for_table.append({"WIN_NUM": "—"})
|
||
if count_column < total_column:
|
||
count_column += 1
|
||
else:
|
||
# print row_for_table
|
||
table_of_win_in_seria_by_apartmment.append({"WIN_IN_APART": row_for_table,
|
||
"APART_NAME": count.sNameApartment,
|
||
"APART_ID": count.id_apart,
|
||
"NUM_OFFERS": min_offer_in_row})
|
||
count_column = 0
|
||
min_offer_in_row = 10000
|
||
row_for_table = []
|
||
# print(table_of_win_in_seria_by_apartmment)
|
||
# print(f"==============>{float(time.time()-tStart2)}<==============")
|
||
# print NumOffersPerColumn, NumMerchantPerColumn
|
||
to_template.update({"WIN_OFFER_AND_MERCHANT": offer_and_merchant_per_win,
|
||
"TABLE_OF_WINDOWS": table_of_win_in_seria_by_apartmment})
|
||
# для "тяжелого шаблона" получаем навигацию страницы, данные для карты и графика ввода в эксплуатацию
|
||
if is_hard_template:
|
||
# если вызывается "тяжелый" шаблон, то нужно подготовить тяжелые данные для построения навигации
|
||
seria_id, for_seria_nav = seria_nav(seria_id)
|
||
to_template.update(for_seria_nav) # данные для навигации по сериям
|
||
to_template.update(seria_info_year(seria_id)) # данные для графика ввода зданий серии в эксплуатацию
|
||
to_template.update(seria_info_geo_code(seria_id)) # данные для карты
|
||
# т.к. обрабатывается "тяжелый шаблон" надо создать "легкий шаблон"
|
||
# для его использования в будущем.
|
||
string_prerender = render_to_string("seria_info/all_seria_info_pre_light.html", to_template)
|
||
file = open(light_template_w_path, 'w')
|
||
# file.write(AA.encode('utf-8'))
|
||
file.write(string_prerender)
|
||
file.close()
|
||
else:
|
||
seria_name = Seria_Info.objects.get(id=seria_id).sName
|
||
to_template.update({'THIS_SERIA_NAME': seria_name})
|
||
|
||
# to_template.update({'LOG_VISIT': GetLastAllUserVisitSeriaList(SeriaName),
|
||
# 'ticks': float(time.time()-time_start)})
|
||
to_template.update({
|
||
# получаем последние визиты клиента через куки
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
# получаем последние визиты всех посетителей из базы
|
||
# id2log, log_visit = get_last_all_user_visit_list()
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)
|
||
})
|
||
return render(request, light_template, to_template)
|
||
|
||
|
||
def seria_nav(seria_id: int = 12) -> (int, dict):
|
||
"""
|
||
Возвращает корректный seria_id и кортеж для построения навигации по сериям дома
|
||
|
||
:param seria_id: id серии
|
||
:return:
|
||
"""
|
||
q_seria = Seria_Info.objects.raw(
|
||
'SELECT oknardia_seria_info.id,'
|
||
' oknardia_seria_info.sName,'
|
||
' oknardia_seria_info.sSeriaDescription,'
|
||
' oknardia_seria_info.kRoot_id,'
|
||
' oknardia_seria_info.kParent_id '
|
||
'FROM oknardia_seria_info '
|
||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||
'ORDER BY oknardia_seria_info.sName;')
|
||
error_seria = True
|
||
for count_seria in q_seria:
|
||
if count_seria.id == int(seria_id):
|
||
error_seria = False
|
||
break
|
||
if error_seria:
|
||
# Ошибочный seria_id. Такой базовой серии нет и надо ее найти.
|
||
try:
|
||
query = Seria_Info.objects.get(id=int(seria_id))
|
||
if query.kRoot_id is not None:
|
||
# базовая серия прописана в kRoot_id
|
||
seria_id = query.kRoot_id
|
||
else:
|
||
# == корневой нет
|
||
# == ищем методом наименьших расстояний"
|
||
min_min = 100000000
|
||
min_id = seria_id
|
||
for count_seria in q_seria:
|
||
if math.fabs(int(seria_id) - count_seria.id) < min_min:
|
||
min_min = math.fabs(int(seria_id) - count_seria.id)
|
||
min_id = count_seria.id
|
||
seria_id = min_id
|
||
except ObjectDoesNotExist:
|
||
seria_id = q_seria[0].id
|
||
# print(f"-->{seria_id}<--")
|
||
return all_seria_nav(seria_id, q_seria)
|
||
|
||
|
||
def all_seria_nav(seria_id: int, q_seria) -> (int, dict):
|
||
seria_nav_dim = []
|
||
this_return = {}
|
||
for count_seria in q_seria:
|
||
one_seria = {}
|
||
one_seria.update({"SERIA_R": count_seria.sName, "ID2URL": count_seria.id})
|
||
if count_seria.id == seria_id:
|
||
this_return.update({"THIS_SERIA_NAME": count_seria.sName,
|
||
"THIS_SERIA_DESCRIPTION": count_seria.sSeriaDescription})
|
||
one_seria.update({"SERIA_L": ""})
|
||
else:
|
||
one_seria.update({"SERIA_L": pytils.translit.slugify(count_seria.sName)})
|
||
seria_nav_dim.append(one_seria)
|
||
this_return.update({"SERIA_NAV_DIM": seria_nav_dim})
|
||
return seria_id, this_return
|
||
|
||
|
||
def seria_info_year(seria_id: int = 12) -> dict:
|
||
""" Возвращает данные для графика распределения сдачи серии в эксплуатацию
|
||
|
||
:param seria_id: int -- id серии для которой нужно получить данные
|
||
:return: dict -- данные для графика распределения сдачи серии в эксплуатацию типа:
|
||
{"DATA4GRAPH": [{'YEAR': 1997, 'NUMS': 1, 'CLRS': '99'},
|
||
{'YEAR': 1998, 'NUMS': 15, 'CLRS': 'сс'},
|
||
{'YEAR': 1998, 'NUMS': 10, 'CLRS': 'a9'}
|
||
]
|
||
}
|
||
"""
|
||
seria_in_years = []
|
||
query = Seria_Info.objects.raw(
|
||
f"SELECT oknardia_building_info.iCommissioning_year as id,"
|
||
f" COUNT(oknardia_building_info.iCommissioning_year) AS NumInYear "
|
||
f"FROM oknardia_building_info"
|
||
f" INNER JOIN oknardia_seria_info"
|
||
f" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id "
|
||
f"WHERE oknardia_seria_info.kRoot_id = {seria_id} "
|
||
f"GROUP BY oknardia_building_info.iCommissioning_year;"
|
||
)
|
||
max_per_year = 0
|
||
graph_color_light = 0xCC # самый светлый цвет на графике (максимальное значение)
|
||
graph_color_dark = 0x99 # самый темный цвет на графике (минимальное значение)
|
||
for YearCount in query:
|
||
if int(YearCount.NumInYear) > max_per_year:
|
||
max_per_year = int(YearCount.NumInYear)
|
||
# print("max", MaxPerYear)
|
||
for YearCount in query:
|
||
data_of_year = {}
|
||
try:
|
||
data_of_year.update({
|
||
"YEAR": int(YearCount.id),
|
||
"NUMS": YearCount.NumInYear,
|
||
"CLRS": str(hex(int(graph_color_dark + YearCount.NumInYear * (
|
||
graph_color_light - graph_color_dark) / max_per_year)))[2:]
|
||
})
|
||
except ValueError:
|
||
continue
|
||
seria_in_years.append(data_of_year)
|
||
# print(seria_in_years)
|
||
return {"DATA4GRAPH": seria_in_years}
|
||
|
||
|
||
def seria_info_geo_code(seria_id: str = '12') -> dict:
|
||
""" Возвращает массив геокоординат зданий одной серии
|
||
|
||
:param seria_id: str -- id серии для которой нужно получить данные
|
||
:return: dict -- массив геокоординат зданий серии
|
||
"""
|
||
data_return = {}
|
||
seria_to_geo = []
|
||
municipal_m2 = 0 # муниципальный фонд (кв.м)
|
||
residential_m2 = 0 # жилой фонд (кв.м)
|
||
government_m2 = 0 # государственные учреждения занимают (кв.м.)
|
||
residents = 0 # количество жильцов
|
||
apartments = 0 # число квартиры
|
||
accounts = 0 # количество лицевых счетов
|
||
condition_max = 0 # максимальное значение показателя состояния здания
|
||
condition_min = 1000000 # минимальное значение показателя состояния здания
|
||
query = Building_Info.objects.raw(
|
||
f"SELECT"
|
||
f" oknardia_building_info.id,"
|
||
f" oknardia_seria_info.kRoot_id as SerId,"
|
||
f" oknardia_building_info.sAddress,"
|
||
f" oknardia_building_info.fResidential_Area,"
|
||
f" oknardia_building_info.fMunicipal_Area,"
|
||
f" oknardia_building_info.fGovernment_Area,"
|
||
f" oknardia_building_info.iNum_Residents,"
|
||
f" oknardia_building_info.iNum_Apartments,"
|
||
f" oknardia_building_info.iNum_Accounts,"
|
||
f" oknardia_building_info.fCondition_House,"
|
||
f" oknardia_building_info.fGeoCode_Latitude,"
|
||
f" oknardia_building_info.fGeoCode_Longitude "
|
||
f"FROM oknardia_building_info"
|
||
f" INNER JOIN oknardia_seria_info"
|
||
f" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id "
|
||
f"WHERE oknardia_seria_info.kRoot_id IN ({seria_id});"
|
||
)
|
||
for count in query:
|
||
if int(count.fGeoCode_Latitude) != 0 and int(count.fGeoCode_Longitude) != 0:
|
||
seria_to_geo.append({"LATITUDE": count.fGeoCode_Latitude,
|
||
"LONGITUDE": count.fGeoCode_Longitude,
|
||
"ADDR_ID": count.id,
|
||
"ADDR_LAT": pytils.translit.slugify(count.sAddress),
|
||
"ADDR_RUS": count.sAddress,
|
||
"SER_ID": count.SerId
|
||
})
|
||
if count.fMunicipal_Area > 0:
|
||
municipal_m2 += count.fMunicipal_Area
|
||
if count.fResidential_Area > 0:
|
||
residential_m2 += count.fResidential_Area
|
||
if count.fGovernment_Area > 0:
|
||
government_m2 += count.fGovernment_Area
|
||
if count.iNum_Residents > 0:
|
||
residents += count.iNum_Residents
|
||
if count.iNum_Residents > 0:
|
||
residents += count.iNum_Residents
|
||
if count.iNum_Apartments > 0:
|
||
apartments += count.iNum_Apartments
|
||
if count.iNum_Accounts > 0:
|
||
accounts += count.iNum_Accounts
|
||
if count.fCondition_House > 0:
|
||
if count.fCondition_House > condition_max:
|
||
condition_max = count.fCondition_House
|
||
if count.fCondition_House < condition_min:
|
||
condition_min = count.fCondition_House
|
||
data_return.update({"DATA4GEO": seria_to_geo,
|
||
"MUNICIPAL_M2": municipal_m2,
|
||
"RESIDENTIAL_M2": residential_m2,
|
||
"GOVERNMENT_M2": government_m2,
|
||
"RESIDENTS": residents,
|
||
"APARTMENTS": apartments,
|
||
"ACCOUNTS": accounts,
|
||
"CONDITION_MAX": condition_max,
|
||
"CONDITION_MIN": condition_min})
|
||
# print(seria_to_geo)
|
||
return data_return
|
||
|
||
|
||
def standard_opening(request: HttpRequest) -> HttpResponse:
|
||
time_start = time.time()
|
||
to_template = {} # словарь, для передачи шаблону
|
||
q_seria = Seria_Info.objects.raw('SELECT oknardia_seria_info.id, oknardia_seria_info.sName '
|
||
'FROM oknardia_seria_info '
|
||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||
'ORDER BY oknardia_seria_info.sName;')
|
||
to_template.update({'SERIAS': list(q_seria)})
|
||
q_win_opening = Win_MountDim.objects.raw(
|
||
'SELECT oknardia_win_mountdim.*,'
|
||
' oknardia_seria_info.sName,'
|
||
' oknardia_seria_info.id AS ID_Seria '
|
||
'FROM oknardia_win_mountdim'
|
||
' INNER JOIN oknardia_mountdim2apartment'
|
||
' ON oknardia_win_mountdim.id = oknardia_mountdim2apartment.kMountDim_id'
|
||
' RIGHT OUTER JOIN oknardia_apartment_type'
|
||
' ON oknardia_apartment_type.id = oknardia_mountdim2apartment.kApartment_id'
|
||
' RIGHT OUTER JOIN oknardia_seria_info'
|
||
' ON oknardia_apartment_type.kSeria_id = oknardia_seria_info.id '
|
||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||
'GROUP BY oknardia_win_mountdim.iWinWidth, oknardia_win_mountdim.iWinHight,'
|
||
' oknardia_win_mountdim.bIsDoor, oknardia_win_mountdim.bIsNearDoor,'
|
||
' oknardia_win_mountdim.sFlapConfig, oknardia_win_mountdim.id,'
|
||
' oknardia_seria_info.sName, oknardia_seria_info.id '
|
||
'ORDER BY oknardia_win_mountdim.iWinWidth DESC,'
|
||
' oknardia_win_mountdim.iWinHight DESC,'
|
||
' oknardia_win_mountdim.bIsNearDoor,'
|
||
' oknardia_win_mountdim.bIsDoor,'
|
||
' oknardia_win_mountdim.id,'
|
||
' oknardia_seria_info.sName;')
|
||
list_windows_opening = []
|
||
tmp_id = 0
|
||
for i in q_win_opening:
|
||
if tmp_id != i.id:
|
||
tmp_id = i.id
|
||
image_file_name = i.sFlapConfig
|
||
image_file_name = image_file_name.replace(">", u"G")
|
||
image_file_name = image_file_name.replace("<", "L")
|
||
image_file_name = image_file_name.replace("|", "I")
|
||
image_file_name = image_file_name.replace("[", "(")
|
||
image_file_name = image_file_name.replace("]", ")")
|
||
image_file_name = image_file_name.replace("/", "-")
|
||
image_file_name = image_file_name.replace("\\", "-")
|
||
image_file_name = image_file_name.replace(".", "-") + u".png"
|
||
image_file_name = f"{PATH_FOR_IMG}/{PATH_FOR_IMGFLAPCONFIG}/{image_file_name}"
|
||
if not os.path.isfile(f"{STATIC_BASE_PATH}/{image_file_name}"):
|
||
make_flap_mini_pictures(f"{STATIC_BASE_PATH}/{image_file_name}", i.sFlapConfig, i.bIsDoor)
|
||
list_windows_opening.append({
|
||
"ID": i.id,
|
||
"INCLUDING_IN_SERIA": [{
|
||
"ID": i.ID_Seria,
|
||
"NAME_T": pytils.translit.slugify(i.sName),
|
||
"NAME": i.sName
|
||
}],
|
||
"INCLUDING_IN_SERIA_ID": [],
|
||
"URL2IMG": image_file_name,
|
||
"FLAP_CONFIG": i.sFlapConfig,
|
||
"DESCRIPTION": i.sDescripion.split(" для")[0].split(" (")[0],
|
||
"DESCRIPTION_L": i.sDescripion,
|
||
"IS_DOOR": i.bIsDoor,
|
||
"IS_NEAR_DOOR": i.bIsNearDoor,
|
||
"H": i.iWinHight * 10,
|
||
"W": i.iWinWidth * 10
|
||
})
|
||
else:
|
||
list_windows_opening[-1]["INCLUDING_IN_SERIA"].append({
|
||
"ID": i.ID_Seria,
|
||
"NAME_T": pytils.translit.slugify(i.sName),
|
||
"NAME": i.sName
|
||
})
|
||
to_template.update({
|
||
'LIST_WIN_OPENING': list_windows_opening,
|
||
# получаем последние визиты клиента через куки
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
# получаем последние визиты всех посетителей из базы
|
||
# id2log, log_visit = get_last_all_user_visit_list()
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)
|
||
})
|
||
return render(request, "catalog/catalog_standard_opening.html", to_template)
|
||
|
||
|
||
def catalog_company(request: HttpRequest) -> HttpResponse:
|
||
time_start = time.time()
|
||
to_template = {} # словарь, для передачи шаблону
|
||
q_company = MerchantBrand.objects.raw('SELECT'
|
||
' oknardia_merchantbrand.id,'
|
||
' oknardia_merchantbrand.sMerchantName,'
|
||
' oknardia_merchantbrand.pMerchantLogo,'
|
||
' oknardia_merchantbrand.sMerchantMainURL,'
|
||
' COUNT(oknardia_priceoffer.id) AS NumOffers,'
|
||
' AVG(oknardia_priceoffer.fOfferPrice) AS PriceAVG,'
|
||
' MAX(oknardia_priceoffer.dOfferModify) AS lastUpdate,'
|
||
' Q.NumSets,'
|
||
' Q.RatingAVG,'
|
||
' 1 AS STARS '
|
||
'FROM (SELECT'
|
||
' COUNT(oknardia_setkit.sSetName) AS NumSets,'
|
||
' oknardia_merchantoffice.kMerchantName_id AS Q_ID,'
|
||
' AVG(oknardia_setkit.fSetRating) AS RatingAVG'
|
||
' FROM oknardia_merchantoffice'
|
||
' INNER JOIN oknardia_ouruser'
|
||
' ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id'
|
||
' INNER JOIN oknardia_setkit'
|
||
' ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id'
|
||
' GROUP BY oknardia_merchantoffice.id,'
|
||
' oknardia_merchantoffice.kMerchantName_id) AS Q,'
|
||
' oknardia_ouruser'
|
||
' INNER JOIN oknardia_merchantoffice'
|
||
' ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id'
|
||
' INNER JOIN oknardia_priceoffer'
|
||
' ON oknardia_priceoffer.kOfferFromUser_id = oknardia_ouruser.id'
|
||
' INNER JOIN oknardia_merchantbrand'
|
||
' ON oknardia_merchantoffice.kMerchantName_id = oknardia_merchantbrand.id'
|
||
' WHERE Q_ID = oknardia_merchantoffice.kMerchantName_id '
|
||
'GROUP BY oknardia_merchantoffice.kMerchantName_id '
|
||
'ORDER BY Q.RatingAVG DESC;')
|
||
list_company = list(q_company)
|
||
for i in list_company:
|
||
i.STARS = get_rating_set_for_stars(i.RatingAVG)
|
||
i.NumSets = pytils.numeral.get_plural(i.NumSets, u"оконный набор, оконных набора, оконных наборов")
|
||
i.NumOffers = pytils.numeral.get_plural(i.NumOffers, u"вариант, варианта, вариантов")
|
||
i.lastUpdate = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.lastUpdate, 'U')))
|
||
i.sMerchantMainURL = pytils.translit.slugify(i.sMerchantName)
|
||
# print("NAME:", i.sMerchantName, "\tNumSets:", i.NumSets, "\tNumOffers:", i.NumOffers,
|
||
# "\t:AverageRating:", i.RatingAVG, "\tAveragePrice:", i.PriceAVG, "\tSTARS:", i.STARS)
|
||
to_template.update({
|
||
'COMPANIES': list_company,
|
||
# получаем последние визиты клиента через куки
|
||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||
# получаем последние визиты всех посетителей из базы
|
||
# id2log, log_visit = get_last_all_user_visit_list()
|
||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||
'ticks': float(time.time() - time_start)
|
||
})
|
||
return render(request, "catalog/catalog_company.html", to_template)
|
||
|
||
# qwzxcvbnm,./890-=12345 |