Fix in Requests + in Report part
This commit is contained in:
@@ -1,21 +1,67 @@
|
||||
from flask import request, Blueprint, render_template
|
||||
from flask import request, Blueprint, render_template, session, url_for
|
||||
from checker import check_auth
|
||||
from os import path
|
||||
from .report_model import sales_report, make_report
|
||||
import json
|
||||
|
||||
with open(path.join(path.dirname(__file__), 'reports.json')) as f:
|
||||
report_list = json.load(f)
|
||||
|
||||
|
||||
report_bp = Blueprint('report_bp', __name__, template_folder='templates')
|
||||
|
||||
@report_bp.route('/', methods=['GET', 'POST'])
|
||||
@report_bp.route('/menu')
|
||||
@check_auth
|
||||
def menu():
|
||||
if request.method == 'GET':
|
||||
return render_template('report_menu.html', options=report_list)
|
||||
|
||||
@report_bp.route('/quaterly', methods=['GET', 'POST'])
|
||||
return render_template('report_menu.html')
|
||||
|
||||
@report_bp.route('/create', methods=['GET', 'POST'])
|
||||
@check_auth
|
||||
def quaterly():
|
||||
def create():
|
||||
if request.method == 'GET':
|
||||
return render_template('quaterly.html')
|
||||
return render_template('report_basic.html',
|
||||
write=True,
|
||||
title='Создание отчета',
|
||||
items = report_list)
|
||||
else:
|
||||
data = dict(month=request.form.get('month'), year=request.form.get('year'))
|
||||
id = request.form.get('category')
|
||||
with open(path.join(path.dirname(__file__), f'access/{id}.json')) as f:
|
||||
report_access = json.load(f)
|
||||
|
||||
if session['role'] in report_access['write']:
|
||||
proc_name = report_access['procedure']
|
||||
ready_report = make_report(data, proc_name)
|
||||
if ready_report.status:
|
||||
return render_template("OK.html")
|
||||
else:
|
||||
return render_template("error.html", error_message=ready_report.error_message)
|
||||
else:
|
||||
return render_template("error.html", error_message='Недостаточно прав для создания данного отчета!')
|
||||
|
||||
@report_bp.route('/view', methods=['GET', 'POST'])
|
||||
@check_auth
|
||||
def view():
|
||||
if request.method == 'GET':
|
||||
return render_template('report_basic.html',
|
||||
write=False,
|
||||
title='Просмотр отчета',
|
||||
items = report_list)
|
||||
else:
|
||||
data = dict(month=request.form.get('month'), year=request.form.get('year'))
|
||||
id = request.form.get('category')
|
||||
with open(path.join(path.dirname(__file__), f'access/{id}.json')) as f:
|
||||
report_access = json.load(f)
|
||||
|
||||
if session['role'] in report_access['read']:
|
||||
ready_report = sales_report(data, report_access['view'])
|
||||
if ready_report.status:
|
||||
title= f'{report_access["title"]} за {data["month"]}-{data["year"]}'
|
||||
return render_template("output.html", items=ready_report.result,
|
||||
header=title,
|
||||
link = url_for('report_bp.menu'))
|
||||
else:
|
||||
return render_template("error.html", error_message=ready_report.error_message)
|
||||
else:
|
||||
return render_template("error.html", error_message='Недосточно прав для чтения данного отчета!')
|
||||
7
App/Report/access/1.json
Normal file
7
App/Report/access/1.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"title" : "Отчет о продажах",
|
||||
"write" : ["Менеджер"],
|
||||
"read" : ["Управляющий"],
|
||||
"view" : "view_report",
|
||||
"procedure" : "generate_report"
|
||||
}
|
||||
34
App/Report/db/DBconnect.py
Normal file
34
App/Report/db/DBconnect.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import pymysql
|
||||
from pymysql.err import *
|
||||
class DBContextManager:
|
||||
def __init__(self, db_config : dict):
|
||||
self.db_config = db_config
|
||||
self.connection = None
|
||||
self.cursor = None
|
||||
|
||||
def __enter__(self):
|
||||
try:
|
||||
self.connection = pymysql.connect(
|
||||
host=self.db_config['host'],
|
||||
port=self.db_config['port'],
|
||||
user=self.db_config['user'],
|
||||
password=self.db_config['password'],
|
||||
db=self.db_config['db']
|
||||
)
|
||||
self.cursor = self.connection.cursor()
|
||||
return self.cursor
|
||||
except (OperationalError, KeyError) as err:
|
||||
print(err.args)
|
||||
return None
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.connection and self.cursor:
|
||||
if exc_type:
|
||||
print(exc_type, '\n', exc_val)
|
||||
self.connection.rollback()
|
||||
else:
|
||||
self.connection.commit()
|
||||
self.cursor.close()
|
||||
self.connection.close()
|
||||
return True
|
||||
|
||||
0
App/Report/db/__init__.py
Normal file
0
App/Report/db/__init__.py
Normal file
14
App/Report/db/sql_provider.py
Normal file
14
App/Report/db/sql_provider.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import os
|
||||
from string import Template
|
||||
|
||||
class SQLProvider:
|
||||
def __init__(self, file_path):
|
||||
self.scripts = {}
|
||||
for file in os.listdir(file_path):
|
||||
_sql = open(f'{file_path}/{file}').read()
|
||||
self.scripts[file] = Template(_sql)
|
||||
|
||||
def get(self, name, params) -> dict:
|
||||
if name not in self.scripts:
|
||||
raise ValueError(f'SQL template {name} not found')
|
||||
return self.scripts[name].substitute(**params)
|
||||
23
App/Report/db/work.py
Normal file
23
App/Report/db/work.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from .DBconnect import DBContextManager
|
||||
|
||||
def select_list(db_config, sql) -> list:
|
||||
with DBContextManager(db_config) as cursor:
|
||||
if cursor is None:
|
||||
raise ValueError("Cursor not created")
|
||||
else:
|
||||
cursor.execute(sql)
|
||||
result = cursor.fetchall()
|
||||
schema = [item[0] for item in cursor.description]
|
||||
lst = [dict(zip(schema, row)) for row in result]
|
||||
return lst
|
||||
|
||||
def procedure(db_config, name, args: tuple):
|
||||
with DBContextManager(db_config) as cursor:
|
||||
if cursor is None:
|
||||
raise ValueError("Cursor not created")
|
||||
else:
|
||||
cursor.callproc(name, args)
|
||||
result = cursor.fetchall()[0]
|
||||
schema = cursor.description[0]
|
||||
lst = dict(zip(schema, result))
|
||||
return lst
|
||||
@@ -1,3 +1,3 @@
|
||||
[
|
||||
{"name": "Квартальный отчет передвижений заготовок", "url": "report_bp.quaterly"}
|
||||
{"id": 1, "name": "Покупки за месяц", "json_file": "access/sales.json"}
|
||||
]
|
||||
4
App/Report/sql/check_report.sql
Normal file
4
App/Report/sql/check_report.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM reports
|
||||
WHERE month = $month AND year = $year
|
||||
) AS exist;
|
||||
@@ -1,11 +0,0 @@
|
||||
SELECT sellers.name AS 'Поставщик',
|
||||
w.date_of_delivery AS 'Дата поставки',
|
||||
SUM(wl.count) AS 'Общее количество заготовок',
|
||||
SUM(wl.price) AS 'Общая стоимость поставленных заготовок'
|
||||
FROM waybill w
|
||||
JOIN waybill_lines wl USING(waybill_id)
|
||||
JOIN workpiece USING(work_id)
|
||||
JOIN sellers USING(sel_id)
|
||||
WHERE workpiece.material = '${material}'
|
||||
AND (w.date_of_delivery BETWEEN '${date_from}' AND '${date_to}')
|
||||
GROUP BY sellers.name, w.date_of_delivery;
|
||||
5
App/Report/sql/view_report.sql
Normal file
5
App/Report/sql/view_report.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
SELECT name_of_product AS 'Наименование',
|
||||
count_of_bought AS 'Количество',
|
||||
sum AS 'Общая стоимость'
|
||||
FROM reports
|
||||
WHERE month = '$month' AND year = '$year';
|
||||
15
App/Report/templates/OK.html
Normal file
15
App/Report/templates/OK.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Успех</title>
|
||||
<link href="/static/css/auth.css" type="text/css" rel="stylesheet">
|
||||
<link href="/static/css/main.css" type="text/css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Успешно!</h1>
|
||||
<p>Отчет успешно добавлен в базу данных!</p>
|
||||
<a href="{{ url_for('index') }}"><button>На главную страницу</button></a>
|
||||
<a href="{{ url_for('report_bp.menu') }}"><button>В меню отчетов</button></a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,18 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Квартальный отчет</title>
|
||||
<link href="/static/css/main.css" type="text/css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="logout">
|
||||
<a href="{{ url_for('logout') }}"><button>Выход</button></a>
|
||||
</div>
|
||||
<!-- Not implemented -->
|
||||
<h1>Заглушка для квартального отчета</h1>
|
||||
<div class="return">
|
||||
<a href="{{ url_for('index') }}"><button>Главное меню</button></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
45
App/Report/templates/report_basic.html
Normal file
45
App/Report/templates/report_basic.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ title }}</title>
|
||||
<link href="/static/css/main.css" type="text/css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="logout">
|
||||
<a href="{{ url_for('logout') }}"><button>Выход</button></a>
|
||||
</div>
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
<form action="" method="post">
|
||||
{% for item in items %}
|
||||
<select name="category" required>
|
||||
<option value="{{ item['id'] }}">{{ item['name'] }}</option>
|
||||
</select>
|
||||
{% endfor %}
|
||||
<select name="month" required>
|
||||
<option value="1">Январь</option>
|
||||
<option value="2">Февраль</option>
|
||||
<option value="3">Март</option>
|
||||
<option value="4">Апрель</option>
|
||||
<option value="5">Май</option>
|
||||
<option value="6">Июнь</option>
|
||||
<option value="7">Июль</option>
|
||||
<option value="8">Август</option>
|
||||
<option value="9">Сентябрь</option>
|
||||
<option value="10">Октябрь</option>
|
||||
<option value="11">Ноябрь</option>
|
||||
<option value="12">Декабрь</option>
|
||||
</select>
|
||||
<input type="number" name="year" value="2024" min="1990" max="2100" required>
|
||||
{% if write %}
|
||||
<button type="submit" value="write">Создать</button>
|
||||
{% else %}
|
||||
<button type="submit" value="read">Просмотр</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="return">
|
||||
<a href="{{ url_for('index') }}"><button>Главное меню</button></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -10,11 +10,10 @@
|
||||
<a href="{{ url_for('logout') }}"><button>Выход</button></a>
|
||||
</div>
|
||||
<h1>Выберите вариант отчетов</h1>
|
||||
<nav class="menu">
|
||||
{% for point in options %}
|
||||
<a href="{{ url_for(point['url']) }}"><button>{{ point['name'] }}</button></a>
|
||||
{% endfor %}
|
||||
</nav>
|
||||
<div style="text-align: center; margin: 20px 0;">
|
||||
<a href="{{ url_for('report_bp.create') }}"><button>Создать отчет</button></a>
|
||||
<a href="{{ url_for('report_bp.view') }}"><button>Читать отчеты</button></a>
|
||||
</div>
|
||||
<div class="return">
|
||||
<a href="{{ url_for('index') }}"><button>Главное меню</button></a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from db.select import select_list
|
||||
from db.sql_provider import SQLProvider
|
||||
from .db.select import select_list
|
||||
from .db.sql_provider import SQLProvider
|
||||
from flask import current_app
|
||||
from os import path
|
||||
|
||||
|
||||
@@ -26,4 +26,6 @@ def index():
|
||||
def logout():
|
||||
session.clear()
|
||||
return render_template('main_menu.html', ses=session)
|
||||
app.run(port=5002, host='0.0.0.0')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(port=5002, host='0.0.0.0')
|
||||
@@ -1,5 +1,11 @@
|
||||
{
|
||||
"Менеджер": ["auth_bp", "requests_bp"],
|
||||
"Управляющий": ["auth_bp", "requests_bp", "report_bp"],
|
||||
"Поставщик": ["auth_bp", "waybill_bp"]
|
||||
}
|
||||
"Менеджер": [
|
||||
"requests_bp",
|
||||
"report_bp"],
|
||||
"Управляющий": [
|
||||
"requests_bp",
|
||||
"report_bp"],
|
||||
"Поставщик": [
|
||||
"waybill_bp"]
|
||||
|
||||
}
|
||||
@@ -11,18 +11,15 @@
|
||||
<a href="{{ url_for('logout') }}"><button>Выход</button></a>
|
||||
</div>
|
||||
<h1>Здравствуйте, {{ ses['login'] }}!</h1>
|
||||
<h2> Ваша роль: {{ ses['role'] }}</h2>
|
||||
{% if ses['access_user'] == 'internal_users' %}
|
||||
<h2> Ваша роль: {{ ses['role'] }}</h2>
|
||||
<!-- Not implemented -->
|
||||
<nav class="menu">
|
||||
<a href="{{ url_for('requests_bp.requests') }}"><button>Запросы</button></a>
|
||||
<a href="{{ url_for('report_bp.menu') }}"><button>Отчеты</button></a>
|
||||
</nav>
|
||||
{% else %}
|
||||
<nav class="menu">
|
||||
<!-- Not implemented -->
|
||||
<a href="{{ url_for('waybill_bp.waybill') }}"><button>Новая накладная</button></a>
|
||||
</nav>
|
||||
<p>Not implemented</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="login">
|
||||
|
||||
Reference in New Issue
Block a user