diff --git a/Material_Categories_import.xlsx b/Material_Categories_import.xlsx new file mode 100644 index 0000000..acf3a5a Binary files /dev/null and b/Material_Categories_import.xlsx differ diff --git a/Material_Sales_import.xlsx b/Material_Sales_import.xlsx new file mode 100644 index 0000000..55d0f85 Binary files /dev/null and b/Material_Sales_import.xlsx differ diff --git a/Materials_importlsx.xlsx b/Materials_importlsx.xlsx new file mode 100644 index 0000000..44f48a7 Binary files /dev/null and b/Materials_importlsx.xlsx differ diff --git a/Resource/masterpol.png b/Resource/masterpol.png new file mode 100644 index 0000000..c192a72 Binary files /dev/null and b/Resource/masterpol.png differ diff --git a/Resource/Мастер пол.ico b/Resource/Мастер пол.ico new file mode 100644 index 0000000..9744b0a Binary files /dev/null and b/Resource/Мастер пол.ico differ diff --git a/Suppliers_import.xlsx b/Suppliers_import.xlsx new file mode 100644 index 0000000..e5b3429 Binary files /dev/null and b/Suppliers_import.xlsx differ diff --git a/link.txt b/link.txt new file mode 100644 index 0000000..c75154e --- /dev/null +++ b/link.txt @@ -0,0 +1,4 @@ +Введите имя файла с партнерами: Suppliers_import.xlsx +Введите имя файла с типами продукции: Material_Categories_import.xlsx +Введите имя файла с продуктами: Materials_importlsx.xlsx +Введите имя файла с продажами: Material_Sales_import.xlsx diff --git a/main.py b/main.py new file mode 100644 index 0000000..e69de29 diff --git a/main_flask.py b/main_flask.py new file mode 100644 index 0000000..e69de29 diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..916c865 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,279 @@ +/* Подключаем шрифт Segoe UI */ +@import url('https://fonts.googleapis.com/css2?family=Segoe+UI:wght@300;400;600;700&display=swap'); + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background-color: #F4E8D3; + margin: 0; + padding: 0; +} + +.main-container { + background-color: #ffffff; + min-height: 100vh; + padding: 20px; +} + +.header { + background: linear-gradient(135deg, #67BA80 0%, #4CAF50 100%); + padding: 20px; + border-radius: 10px; + margin-bottom: 30px; + color: white; +} + +.logo-container { + display: flex; + align-items: center; + gap: 20px; +} + +.logo { + height: 60px; + width: auto; + object-fit: contain; +} + +.header-title { + font-size: 2.2em; + font-weight: 700; + margin: 0; + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +.page-title { + color: #2c3e50; + font-weight: 600; +} + +.partner-card { + border: 2px solid #67BA80; + border-radius: 12px; + padding: 20px; + margin-bottom: 20px; + background: #ffffff; + box-shadow: 0 4px 12px rgba(103, 186, 128, 0.15); +} + +.partner-header { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 2px solid #e9ecef; + padding-bottom: 15px; + margin-bottom: 15px; +} + +.partner-name-line { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; +} + +.partner-type { + font-size: 1.3em; + font-weight: 600; + color: #6c757d; + background: #f8f9fa; + padding: 6px 14px; + border-radius: 20px; +} + +.partner-name { + font-size: 1.4em; + font-weight: 700; + color: #2c3e50; + margin: 0; +} + +.divider { + color: #dee2e6; + font-weight: bold; + font-size: 1.4em; +} + +.discount-info { + display: flex; + align-items: center; + gap: 15px; +} + +.discount-badge { + font-size: 1.1em; + padding: 8px 16px; + border-radius: 25px; + background-color: #67BA80; + color: white; +} + +.sales-amount { + font-size: 1em; + color: #6c757d; + font-weight: 500; +} + +.partner-info-row { + margin-bottom: 0; + padding: 6px 0; + line-height: 1.4; +} + +.partner-label { + font-weight: 600; + color: #495057; + min-width: 100px; + display: inline-block; + font-size: 1em; +} + +.partner-value { + font-size: 1em; + color: #2c3e50; +} + +.partner-buttons-container { + display: flex; + gap: 12px; + justify-content: flex-start; + margin-top: 20px; + padding-top: 15px; + border-top: 2px solid #e9ecef; +} + +.btn-action { + padding: 10px 20px; + font-size: 0.95em; + display: flex; + align-items: center; + gap: 8px; + min-width: 180px; + justify-content: center; + border: none; + border-radius: 8px; + font-weight: 600; + transition: all 0.3s ease; +} + +.btn-edit { + background-color: #67BA80; + color: white; +} + +.btn-add { + background-color: #6c757d; + color: white; +} + +.btn-history { + background-color: #495057; + color: white; +} + +.btn-action:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0,0,0,0.2); + color: white; +} + +.btn-new-partner { + background-color: #67BA80; + color: white; + border: none; + padding: 12px 24px; + font-weight: 600; + border-radius: 8px; +} + +.btn-new-partner:hover { + background-color: #5aa870; + color: white; +} + +.rating-badge { + font-size: 0.9em; + padding: 6px 12px; + border-radius: 15px; +} + +.alert { + border-radius: 10px; + border: none; +} +.partner-info-row:last-child { + margin-bottom: 10px; +} + +.volume-info { + background-color: #f8f9fa; + padding: 8px 12px; + border-radius: 6px; + margin-top: 10px; +} + +.volume-label { + font-weight: 600; + color: #495057; +} + +.volume-value { + color: #2c3e50; + font-weight: 500; +} + +/* Стили для страницы истории продаж */ +/* Стили для таблицы продаж */ +.table-responsive { + border-radius: 8px; + overflow: hidden; +} + +.table { + margin-bottom: 0; +} + +.table th { + background-color: #67BA80; + color: white; + font-weight: 600; + padding: 12px; + text-align: center; +} + +.table td { + padding: 10px; + text-align: center; + vertical-align: middle; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(103, 186, 128, 0.05); +} + +.table-striped tbody tr:hover { + background-color: rgba(103, 186, 128, 0.1); +} + +.table tfoot { + background-color: #e8f5e8; + font-weight: 600; +} + +.table tfoot td { + border-top: 2px solid #67BA80; +} + +.text-end { + text-align: right !important; +} + +/* Адаптивность для таблицы */ +@media (max-width: 768px) { + .table-responsive { + font-size: 0.9em; + } + + .table th, .table td { + padding: 6px; + } +} \ No newline at end of file diff --git a/static/js/script.js b/static/js/script.js new file mode 100644 index 0000000..f5b0daa --- /dev/null +++ b/static/js/script.js @@ -0,0 +1,37 @@ +document.addEventListener('DOMContentLoaded', function() { + // Кнопка нового партнера + const newPartnerBtn = document.querySelector('.btn-new-partner'); + if (newPartnerBtn) { + newPartnerBtn.addEventListener('click', function() { + // Переход на страницу добавления партнера + window.location.href = '/add_partner'; + }); + } + + // Кнопка "Редактирование" + document.querySelectorAll('.btn-edit').forEach(btn => { + btn.addEventListener('click', function() { + const partnerId = this.getAttribute('data-partner-id'); + // Переход на страницу редактирования + window.location.href = `/edit_partner/${partnerId}`; + }); + }); + + // Кнопка "Добавление продажи" + document.querySelectorAll('.btn-add').forEach(btn => { + btn.addEventListener('click', function() { + const partnerId = this.getAttribute('data-partner-id'); + // Переход на страницу добавления продажи + window.location.href = `/add_sale/${partnerId}`; + }); + }); + + // Кнопка "История реализации" + document.querySelectorAll('.btn-history').forEach(btn => { + btn.addEventListener('click', function() { + const partnerId = this.getAttribute('data-partner-id'); + // Переход на страницу истории реализации + window.location.href = `/sales_history/${partnerId}`; + }); + }); +}); \ No newline at end of file diff --git a/static/masterpol.png b/static/masterpol.png new file mode 100644 index 0000000..c192a72 Binary files /dev/null and b/static/masterpol.png differ diff --git a/static/Мастер пол.ico b/static/Мастер пол.ico new file mode 100644 index 0000000..9744b0a Binary files /dev/null and b/static/Мастер пол.ico differ diff --git a/templates/about.html b/templates/about.html new file mode 100644 index 0000000..77fdb9f --- /dev/null +++ b/templates/about.html @@ -0,0 +1,18 @@ + + + + + About Flask + + + {% extends "template.html" %} + {% block content %} + +

About Flask

+

Flask is a micro web framework written in Python.

+

Applications that use the Flask framework include Pinterest, + LinkedIn, and the community web page for Flask itself.

+ + {% endblock %} + + \ No newline at end of file diff --git a/templates/add_partner.html b/templates/add_partner.html new file mode 100644 index 0000000..cc61b0f --- /dev/null +++ b/templates/add_partner.html @@ -0,0 +1,67 @@ +{% extends "base.html" %} + +{% block content %} +
+

Добавление нового партнера

+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
+ {{ message }} +
+ {% endfor %} + {% endif %} + {% endwith %} + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + + Отмена +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/add_sale.html b/templates/add_sale.html new file mode 100644 index 0000000..95878ae --- /dev/null +++ b/templates/add_sale.html @@ -0,0 +1,182 @@ +{% extends "base.html" %} + +{% block content %} +
+
+
+
+
+

+ Добавление продажи +

+
+
+ +
+
Партнер: {{ partner.name }}
+

Тип: {{ partner.partner_type_name }}

+

Email: {{ partner.email }}

+

Телефон: {{ partner.phone or 'Не указан' }}

+
+ + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
+ {{ message }} + +
+ {% endfor %} + {% endif %} + {% endwith %} + +
+
+
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
Минимальная цена: 0 руб.
+
+ +
+ + +
+
+
+ + +
+
+
+
+
+ Количество: + 1 ед. +
+
+ Цена за единицу: + 0 руб. +
+
+ Итоговая сумма: + 0 руб. +
+
+
+
+
+ +
+
+
+ + Назад к истории + + +
+
+
+
+
+
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..6a4729f --- /dev/null +++ b/templates/base.html @@ -0,0 +1,26 @@ + + + + + + {% block title %}MasterPol - Управление партнерами{% endblock %} + + + + + + +
+
+ {% block header %} + {% include 'components/header.html' %} + {% endblock %} + + {% block content %} + {% endblock %} +
+
+ + + + \ No newline at end of file diff --git a/templates/components/header.html b/templates/components/header.html new file mode 100644 index 0000000..9130468 --- /dev/null +++ b/templates/components/header.html @@ -0,0 +1,6 @@ +
+
+ +

Управление партнерами

+
+
\ No newline at end of file diff --git a/templates/components/partner_card.html b/templates/components/partner_card.html new file mode 100644 index 0000000..facdadd --- /dev/null +++ b/templates/components/partner_card.html @@ -0,0 +1,73 @@ +
+
+ +
+
+ + {% if partner.partner_type_name %} + {{ partner.partner_type_name }} + {% else %} + Тип не указан + {% endif %} + + | + {{ partner.name }} +
+ +
+ + Скидка {{ partner.discount_percent }}% + + + {{ partner.total_quantity }} ед. + +
+
+ + +
+ Директор: + {{ partner.director or 'Не указан' }} +
+ +
+ Телефон: + + {% if partner.phone %} + {{ partner.phone }} + {% else %} + Не указан + {% endif %} + +
+ +
+ Рейтинг: + + + {{ partner.rating }} + + +
+ +
+ Объем продаж: + + {{ "%.2f"|format(partner.total_sales) }} руб. + +
+ + +
+ + + +
+
+
\ No newline at end of file diff --git a/templates/edit_partner.html b/templates/edit_partner.html new file mode 100644 index 0000000..97a339f --- /dev/null +++ b/templates/edit_partner.html @@ -0,0 +1,142 @@ +{% extends "base.html" %} + +{% block content %} +
+
+
+
+
+

+ Редактирование партнера +

+
+
+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
+ {{ message }} + +
+ {% endfor %} + {% endif %} + {% endwith %} + +
+
+ +
+
Основная информация
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
От 0.0 до 5.0
+
+
+ + +
+
Контактная информация
+ +
+ + +
+ +
+ + +
+ +
+ + +
10 или 12 цифр
+
+ +
+ + +
+
+
+ +
+
+
+ + Назад к списку + +
+ + История продаж + + +
+
+
+
+
+
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} \ No newline at end of file diff --git a/templates/home.html b/templates/home.html new file mode 100644 index 0000000..085f57c --- /dev/null +++ b/templates/home.html @@ -0,0 +1,16 @@ + + + + + Flask Tutorial + + + {% extends "template.html" %} + {% block content %} + +

My First Try Using Flask

+

Flask is Fun

+ + {% endblock %} + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..59a3a28 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} + +{% block content %} + +
+

Список партнеров

+ + Новый партнер + +
+ + {% if partners %} +
+ {% for partner in partners %} + {% include 'components/partner_card.html' %} + {% endfor %} +
+ {% else %} +
+ Нет данных о партнерах +
+ {% endif %} +{% endblock %} \ No newline at end of file diff --git a/templates/sales_history.html b/templates/sales_history.html new file mode 100644 index 0000000..a17c2a9 --- /dev/null +++ b/templates/sales_history.html @@ -0,0 +1,141 @@ +{% extends "base.html" %} + +{% block title %}История продаж - {{ partner.name }}{% endblock %} + +{% block content %} +
+ +
+
+ + Назад + +

История продаж - {{ partner.name }}

+
+
+ + +
+
+
+ + {% if partner.partner_type_name %} + {{ partner.partner_type_name }} + {% else %} + Тип не указан + {% endif %} + + | + {{ partner.name }} +
+
+ +
+
+
+
+ Директор: + {{ partner.director or 'Не указан' }} +
+
+ Телефон: + {{ partner.phone or 'Не указан' }} +
+
+
+
+ Email: + {{ partner.email or 'Не указан' }} +
+
+ ИНН: + {{ partner.inn or 'Не указан' }} +
+
+
+
+
+ + +
+

Общая статистика

+
+
+
+
{{ total_stats.total_sales or 0 }}
+
Всего продаж
+
+
+
+
+
{{ total_stats.total_quantity or 0 }}
+
Общее количество
+
+
+
+
+
{{ "%.2f"|format(total_stats.total_amount or 0) }} руб.
+
Общая сумма
+
+
+
+
+
{{ "%.2f"|format(total_stats.avg_price or 0) }} руб.
+
Средняя цена
+
+
+
+
+ + +
+

Детализация продаж

+ + {% if sales %} +
+ + + + + + + + + + + + + + + {% for sale in sales %} + + + + + + + + + + + {% endfor %} + + + + + + + + + + +
Дата продажиТоварАртикулТип товараКоличествоЦена за ед.Общая суммаДата создания
{{ sale.sale_date }}{{ sale.product_name or 'Неизвестный товар' }}{{ sale.product_article or '-' }}{{ sale.product_type_name or '-' }}{{ sale.quantity }} ед.{{ "%.2f"|format(sale.sale_price) }} руб.{{ "%.2f"|format(sale.quantity * sale.sale_price) }} руб.{{ sale.created_at[:10] if sale.created_at else '-' }}
Итого:{{ total_stats.total_quantity or 0 }} ед.{{ "%.2f"|format(total_stats.avg_price or 0) }} руб.{{ "%.2f"|format(total_stats.total_amount or 0) }} руб.
+
+ {% else %} +
+ Нет данных о продажах +
+ {% endif %} +
+
+{% endblock %} \ No newline at end of file