From 4e03fead6736ed98955a7eac427f825687f5181e Mon Sep 17 00:00:00 2001 From: erjemin Date: Thu, 29 Dec 2022 15:46:16 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8C=D1=8E=D1=88=D0=BA=D0=B0=20=D0=B8?= =?UTF-8?q?=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD:=20"=D0=9A=D0=B0=D1=82?= =?UTF-8?q?=D0=B0=D0=BB=D0=BE=D0=B3=20/=20=D0=9F=D1=80=D0=BE=D0=B8=D0=B7?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B8=20=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BE=D0=BA=D0=BE=D0=BD=20/=20=D0=9A=D0=BE=D0=BC=D0=BF=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F"=20--=20=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oknardia/oknardia/urls.py | 1 + .../catalog/catalog_company_detail.html | 140 ++++++++++++++++++ oknardia/web/catalog.py | 92 +++++++++++- 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100755 oknardia/templates/catalog/catalog_company_detail.html diff --git a/oknardia/oknardia/urls.py b/oknardia/oknardia/urls.py index fbab880..56a10a3 100644 --- a/oknardia/oknardia/urls.py +++ b/oknardia/oknardia/urls.py @@ -66,6 +66,7 @@ urlpatterns = [ re_path(r'^catalog/standard_opening[/*]$', catalog.standard_opening), # --- --- Каталог производителей окон re_path(r'^catalog/company[/*]$', catalog.catalog_company), + re_path(r'^catalog/company/(?P\d+)-(?P\S*)[/*]$', catalog.catalog_company_detail), ] diff --git a/oknardia/templates/catalog/catalog_company_detail.html b/oknardia/templates/catalog/catalog_company_detail.html new file mode 100755 index 0000000..9b2767e --- /dev/null +++ b/oknardia/templates/catalog/catalog_company_detail.html @@ -0,0 +1,140 @@ +{% extends "base.html" %} +{% load static %}{% load filters %} + +{% block Title %}Окна «{{ COMPANY }}» : Каталог производителей окон{% endblock %} + +{% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %} + +{% block Description %}«{{ COMPANY }}», описание компании «{{ COMPANY }}», оконные наборы от «{{ COMPANY }}» и их состав, характеристики «{{ COMPANY }}», рейтинг «{{ COMPANY }}», средние цены и отклонение цен «{{ COMPANY }}».{% endblock %} + +{% block Keywords %}{{ COMPANY }}, компания {{ COMPANY }}, окна {{ COMPANY }}, изготовитель окон {{ COMPANY }}, производитель окон {{ COMPANY }}, поставщик окон {{ COMPANY }}, партнёр, каталог компаний, каталог оконных компаний, oknardia, окнардия {{ META_KEYWORDS|default:"" }} {% endblock %} + +{% block Date4Meta %}{% if PUB_DAT %}{{ PUB_DAT|date:"c" }}{% else %}{% now "c" %}{% endif %}{% endblock %} + +{% block Last4Meta %}{% if PUB_DAT %}{{ PUB_DAT|date:"c" }}{% else %}{% now "c" %}{% endif %}{% endblock %} + +{% block Author4Meta %}: Каталог изготовителей окон{% endblock %} + +{% block CopyrightAuthor4Meta %}: Каталог изготовителей окон{% endblock %} + +{% block Top_Meta1 %}{# #} + {% if IMG_FOR_BLOG %} + {% else %} + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{# #}{% endblock %} + + +{% block Main_Content %} +
+ {# #}{# #} +
{% for i in SETS %} + {# ЛЕВАЯ КОЛОНКА: НАЧАЛО #}
{% if forloop.first %} +

{% if i.sMerchantDescription %} +

{{ i.sMerchantDescription|safe }}

{% endif %} + + + + + + + + + {% if i.sOfficeDescription %} + + + {% endif %} + + + + + + + + + + + + + + + +
Контактная информация:
телефоны:{{ i.sOfficePhones|safe }}
часы работы:{{ i.sOfficeDescription|safe }}
email:
сайт:{{ i.sMerchantMainURL.URL_VIEW }}
офис*:{{ i.sOfficeName }}
адрес:
+

* — Офис предоставивший расчеты для оконного агрегатора «Окнардия».

+ {% endif %}
{# ЛЕВАЯ КОЛОНКА: КОНЕЦ #} + + {# ПРАВАЯ КОЛОНКА: НАЧАЛО #}
+ + + + + +

Оконный набор: «{{ i.sSetName|safe }}»

{% for Star in i.fSetRating.STARS %}{% if Star == 0 %}{% else %}{% endif %}{% endfor %} {% if i.fSetRating.RATING > -0.01 %} {{ i.fSetRating.RATING|stringformat:".2f" }}{% endif %}
+ +

В этом наборе применен {% if i.iProfileCameras != "—" %}профиль {{ i.sProfileBriefDescription }}{% else %} {{ i.sProfileBriefDescription|lower }}{% endif %} производства {{ i.sProfileManufacturer.NAME }}. {% if i.iProfileCameras != "—"%} Число камер рамы и створки — {{ i.iProfileCameras }}.{% endif %} {{ i.fProfileSeals|capfirst }} уплотнения. {% if i.iProfileCameras in LIST_NOT %}Основа: {% else %}Армирование {% endif %} {{ i.sProfileReinforcement }}. Цвет профиля: {{ i.sProfileColor|lower }}. Устанавливается {{ i.sGlazingBriefDescription|lower|safe }}{% if i.sGlazingManufacturer != "—//—" %}{% if i.sGlazingManufacturer not in LIST_NOT %}, производства {{ i.sGlazingManufacturer }}{% endif %}{% endif %}. {% if i.sGlazingToning|lower == "нет" %}Без тонирования{% else %}Тонирование: {{ i.sGlazingToning|lower }}{% endif %}. Формула стеклопакета: {{ i.sGlazingMark }}. Цвет уплотнителя контуров и стеклопакета {{ i.sProfileSealDescription }}. Используется фурнитура {{ i.sSetImplementAll }}{% if i.sSetImplementHandles != "" %}, ручки {{ i.sSetImplementHandles }}{% endif %}{% if i.sSetImplementCatch != "" %}, фиксатор открывания {{ i.sSetImplementCatch }}{% endif %}. {% if i.sSetClimateControl != "" %} Каждое окно оборудовано системой климат-контроля — {{ i.sSetClimateControl }}.{% endif %}

+

{% if i.sSetSill|lower not in LIST_NOT %}Оконный подоконник {{ i.sSetSill|safe }}.{% endif %} {% if i.sSetPanes|lower not in LIST_NOT %}Внешний водоотлив {{ i.sSetPanes|safe }}.{% endif %} {% if i.sSetSlope|lower not in LIST_NOT %}Внутренй откос {{ i.sSetSlope|safe }}.{% endif %}{% if i.sSetSill|lower in LIST_NOT and i.sSetPanes|lower in LIST_NOT and i.sSetSlope|lower in LIST_NOT %}Подоконники, внешние водоотливы и внутренние откосы не включены в набор. Производитель «{{ COMPANY }}» предполагает, что закзчик этого набора закупит их отдельно у него или других поставщиков.{% elif i.sSetSill|lower in LIST_NOT and i.sSetPanes|lower in LIST_NOT %}Подоконники и внешние водоотливы не включены в набор. Производитель «{{ COMPANY }}» предполагает, что закзчик этого набора закупит их отдельно у него или других поставщиков.{% elif i.sSetSill|lower in LIST_NOT and i.sSetSlope|lower in LIST_NOT %}Внешние водоотливы и внутренние откосы не включены в набор. Производитель «{{ COMPANY }}» предполагает, что закзчик этого набора закупит их отдельно у него или других поставщиков.{% elif i.sSetPanes|lower in LIST_NOT and i.sSetSlope|lower in LIST_NOT %}Подоконники и внутренние откосы не включены в набор. Производитель «{{ COMPANY }}» предполагает, что закзчик этого набора закупит их отдельно у него или других поставщиков.{% elif i.sSetPanes|lower in LIST_NOT %}Внешние оконные водоотливы не включены в набор. Производитель «{{ COMPANY }}» предполагает, что закзчик этого набора закупит их отдельно у него или других поставщиков.{% elif i.sSetSlope|lower in LIST_NOT %}Внутренние откосы и их отделка не включены в набор. Производитель «{{ COMPANY }}» предполагает, что закзчик этого набора закупит их отдельно у него или других поставщиков.{% elif i.sSetSill|lower in LIST_NOT %}Оконные подоконники не включены в набор. Производитель «{{ COMPANY }}» предполагает, что закзчик этого набора закупит их отдельно у него или других поставщиков.{% endif %}

+

{% if i.bSetUninstallInstall %}Установка новых и демонтаж старых оконых конструкций {{ i.sSetUninstallInstall|safe }}. {% endif %}{% if i.bSetDelivery %}Доставка {{ i.sSetDelivery|safe }}. {% endif %}{% if not i.bSetDelivery and not i.bSetUninstallInstall %}В стоимость набора не входит демонтаж и установка. Эти услуги оплачиваются отдельно. {% if i.sSetUninstallInstall not in LIST_NOT %}Примерно {{ i.sSetUninstallInstall|safe }}, или заказчик может провести все работы самостоятельно. {% endif %}Доставка тоже не входит в стоимость, осуществляется заказчиком самостоятельно или оплачивается отдельно. {% if i.sSetUninstallInstall not in LIST_NOT %}{{ i.sSetDelivery|safe|capfirst }}. {% endif %}{% elif not i.bSetDelivery %}Доставка не входит в стоимость, осуществляется заказчиком самостоятельно или оплачивается отдельно. {% if i.sSetUninstallInstall not in LIST_NOT %}{{ i.sSetDelivery|safe|capfirst }}. {% endif %}{% elif not i.bSetUninstallInstall %}В стоимость набора не входит демонтаж и установка. Эти услуги оплачиваются отдельно.{% if i.sSetUninstallInstall not in LIST_NOT %} Примерно {{ i.sSetUninstallInstall|safe }}. Или заказчик может провести все работы самостоятельно.{% endif %}{% endif %}

{% if i.sSetOtherConditions not in LIST_NOT %} +

Прочие условия — {{ i.sSetOtherConditions|safe }}

{% endif %} +{# Скидки -- {{ i.sOfficeDiscountMetaFormula }}
#} + +

Извините, графики ценового распределения для оконного набора «{{ i.sSetName|safe }}» компании «{{ i.sMerchantName }}» подготавливаются.
 
Зайдите позже.

+

Оконный набор создан {{ i.earlyCreation }}, последнее обновление цен {{ i.lastUpdate }}

+ +
{# ПРАВАЯ КОЛОНКА: КОНЕЦ #}{% endfor %} + {# РАСПОРКА: начало #}
{# РАСПОРКА: конец #} +
+ {# --- Баннер: НАЧАЛО --- #} +

{% include "ad/bannet-wide.html" %}
+ {# --- Баннер: конец --- #} +
+{% include "report/report_last_user_visit.html" %} +{% include "report/report_log_user_visit.html" %} +
+
{% endblock %} + + + + diff --git a/oknardia/web/catalog.py b/oknardia/web/catalog.py index 76ec2bc..ca4898c 100644 --- a/oknardia/web/catalog.py +++ b/oknardia/web/catalog.py @@ -949,4 +949,94 @@ def catalog_company(request: HttpRequest) -> HttpResponse: }) return render(request, "catalog/catalog_company.html", to_template) -# qwzxcvbnm,./890-=12345 \ No newline at end of file + +def catalog_company_detail(request: HttpRequest, company_id: str, company_name_slug: str) -> HttpResponse: + time_start = time.time() + to_template = {} # словарь, для передачи шаблону + company_id = int(company_id) + q_by_id = MerchantBrand.objects.get(id=company_id) + if pytils.translit.slugify(q_by_id.sMerchantName) != company_name_slug: + return redirect('/catalog/company/%d-%s' % (company_id, pytils.translit.slugify(q_by_id.sMerchantName))) + to_template.update({'COMPANY': q_by_id.sMerchantName}) + to_template.update({'COMPANY_ID': company_id}) + to_template.update({'COMPANY_T': company_name_slug}) + list_not = [u"нет", u"—", ""] + to_template.update({'LIST_NOT': list_not}) + q_sets = MerchantBrand.objects.raw(f"SELECT" + f" COUNT(oknardia_priceoffer.id) AS NumOffers," + f" AVG(oknardia_priceoffer.fOfferPrice) AS priceAVG," + f" MAX(oknardia_priceoffer.dOfferModify) AS lastUpdate," + f" MIN(oknardia_priceoffer.dOfferCreate) AS earlyCreation," + f" oknardia_merchantbrand.*," + f" oknardia_merchantoffice.*," + f" oknardia_merchantoffice.id AS idMERCH," + f" oknardia_setkit.*," + f" oknardia_setkit.id AS idSET," + f" oknardia_pvcprofiles.*," + f" oknardia_pvcprofiles.id AS idPVC," + f" oknardia_glazing.*, " + f" oknardia_glazing.id AS idGLAZ " + f"FROM oknardia_ouruser" + 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" INNER JOIN oknardia_setkit" + f" ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id" + f" INNER JOIN oknardia_priceoffer" + 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_glazing" + f" ON oknardia_setkit.kSet2Glazing_id = oknardia_glazing.id " + f"WHERE oknardia_merchantbrand.id = {company_id} " + f"AND oknardia_priceoffer.sOfferActive = TRUE " + f"GROUP BY oknardia_merchantoffice.id," + f" oknardia_setkit.id," + f" oknardia_setkit.fSetRating " + f"ORDER BY oknardia_setkit.fSetRating DESC;") + list_sets = list(q_sets) + for i in list_sets: + i.sMerchantMainURL = {"URL": i.sMerchantMainURL, + "URL_VIEW": re.sub(r"(?:^http://|^https://|/$|www\.)", "", i.sMerchantMainURL)} + k = random.randint(1, int(len(i.sOfficeEmails)/2) - 1) + i.sOfficeEmails = [i.sOfficeEmails[0:k], i.sOfficeEmails[k:-k], i.sOfficeEmails[-k:]] + to_template.update({'IMG_FOR_BLOG': i.pMerchantLogo}) + i.fSetRating = {"RATING": i.fSetRating, + "STARS": get_rating_set_for_stars(i.fSetRating)} + i.lastUpdate = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.lastUpdate, 'U'))) + i.earlyCreation = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.earlyCreation, 'U'))) + i.sProfileName = {"NAME": i.sProfileName, + "NAME_T": pytils.translit.slugify(i.sProfileName)} + i.sProfileManufacturer = {"NAME": i.sProfileManufacturer, + "NAME_T": pytils.translit.slugify(i.sProfileManufacturer)} + i.fProfileSeals = pytils.numeral.sum_string(i.fProfileSeals, pytils.numeral.MALE, u"контур, контура, контуров") + if i.sSetImplementCatch.lower() in list_not: + i.sSetImplementCatch = "" + if i.sSetClimateControl.lower() in list_not: + i.sSetClimateControl = "" + if len(i.sProfileReinforcement) > 0: + i.sProfileReinforcement = i.sProfileReinforcement[0].lower()+i.sProfileReinforcement[1:] + if len(i.sSetSill) > 0: + i.sSetSill = i.sSetSill[0].lower()+i.sSetSill[1:] + if len(i.sSetPanes) > 0: + i.sSetPanes = i.sSetPanes[0].lower()+i.sSetPanes[1:] + if len(i.sSetSlope) > 0: + i.sSetSlope = i.sSetSlope[0].lower()+i.sSetSlope[1:] + if len(i.sSetUninstallInstall) > 0: + i.sSetUninstallInstall = i.sSetUninstallInstall[0].lower()+i.sSetUninstallInstall[1:] + if len(i.sSetDelivery) > 0: + i.sSetDelivery = i.sSetDelivery[0].lower()+i.sSetDelivery[1:] + if len(i.sSetOtherConditions) > 0: + i.sSetOtherConditions = i.sSetOtherConditions[0].lower()+i.sSetOtherConditions[1:] + to_template.update({ + 'SETS': list_sets, + # получаем последние визиты клиента через куки + '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) + }) + response = render (request, "catalog/catalog_company_detail.html", to_template) + return response \ No newline at end of file