bpappbuilder 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/PKG-INFO +2 -2
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/README.md +1 -1
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/pyproject.toml +1 -1
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/__init__.py +1 -1
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/reports/__init__.py +4 -1
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/reports/report.py +98 -4
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/.github/workflows/python-publish.yml +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/.gitignore +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/LICENSE +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/apps/development360/development360.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/apps/technoholding/technoholding.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/apps/vunderkind/vunderkind.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/__init__.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/app.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/db.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/styles.qss +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/themes.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/fields/__init__.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/fields/combo_box_items.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/fields/field.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/processes/__init__.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/processes/process.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/processes/task.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/__init__.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/group.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/tab.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/table.py +0 -0
- {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/table_tab.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bpappbuilder
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Оболочка над PyQt для создания приложений, как в 1С:Предприятии, но на Python
|
|
5
5
|
Author: AlexK-1
|
|
6
6
|
License-Expression: MIT
|
|
@@ -21,7 +21,7 @@ Description-Content-Type: text/markdown
|
|
|
21
21
|
|
|
22
22
|
## TODOs
|
|
23
23
|
- [X] Реализовать бизнес-процессы и задачи
|
|
24
|
-
- [
|
|
24
|
+
- [X] Создать отчёты в виде календаря
|
|
25
25
|
- [ ] Добавить возможность делать поля невидимыми в формах/таблицах
|
|
26
26
|
- [ ] Добавить возможность настраивать кнопки форм
|
|
27
27
|
- [ ] Сделать автоматическое обновление вкладок
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## TODOs
|
|
8
8
|
- [X] Реализовать бизнес-процессы и задачи
|
|
9
|
-
- [
|
|
9
|
+
- [X] Создать отчёты в виде календаря
|
|
10
10
|
- [ ] Добавить возможность делать поля невидимыми в формах/таблицах
|
|
11
11
|
- [ ] Добавить возможность настраивать кнопки форм
|
|
12
12
|
- [ ] Сделать автоматическое обновление вкладок
|
|
@@ -13,9 +13,12 @@ from .report import (
|
|
|
13
13
|
LineChartReport,
|
|
14
14
|
BarChartReport,
|
|
15
15
|
PieChartReport,
|
|
16
|
+
CalendarColors,
|
|
17
|
+
CalendarReport,
|
|
16
18
|
ReportTab
|
|
17
19
|
)
|
|
18
20
|
|
|
19
21
|
__all__ = ["ReportSettingsItem", "TextReportField", "GetTableWidget", "CreateTextReportHandler",
|
|
20
22
|
"CreateTableReportHandler", "ReportSection", "TextReport", "ListReport", "TableTotalFn",
|
|
21
|
-
"TableTotal", "TableReport", "LineChartReport", "BarChartReport", "PieChartReport",
|
|
23
|
+
"TableTotal", "TableReport", "LineChartReport", "BarChartReport", "PieChartReport",
|
|
24
|
+
"CalendarColors", "CalendarReport", "ReportTab"]
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
from PySide6.QtWidgets import (QWidget, QLabel, QSplitter, QGroupBox, QPushButton, QMessageBox,
|
|
2
2
|
QTableWidget, QHeaderView, QStyleOptionHeader, QTableView,
|
|
3
|
-
QVBoxLayout, QLayout, QFormLayout)
|
|
3
|
+
QVBoxLayout, QLayout, QFormLayout, QCalendarWidget)
|
|
4
4
|
from PySide6.QtCharts import (QChart, QChartView, QScatterSeries, QLineSeries, QCategoryAxis,
|
|
5
5
|
QValueAxis, QBarSet, QBarSeries, QBarCategoryAxis, QPieSeries,
|
|
6
6
|
QPieSlice)
|
|
7
|
-
from PySide6.QtCore import Qt, QRect, QAbstractTableModel, QModelIndex
|
|
8
|
-
from PySide6.QtGui import QPainter
|
|
7
|
+
from PySide6.QtCore import Qt, QRect, QAbstractTableModel, QModelIndex, QDate, QDateTime
|
|
8
|
+
from PySide6.QtGui import QPainter, QColor, QPalette
|
|
9
9
|
|
|
10
10
|
from ..app.db import DataBase
|
|
11
11
|
from ..tabs.tab import Tab
|
|
12
12
|
from ..tabs.table import FormFieldWidget
|
|
13
13
|
from ..tabs.table_tab import TableTab
|
|
14
|
-
from ..fields.field import Field
|
|
14
|
+
from ..fields.field import Field, DateTimeField
|
|
15
15
|
|
|
16
16
|
from typing import Optional, Union, Sequence, Any, Callable, Iterable
|
|
17
17
|
from abc import ABC, abstractmethod
|
|
@@ -898,6 +898,100 @@ class PieChartReport(ReportSection):
|
|
|
898
898
|
return widget
|
|
899
899
|
|
|
900
900
|
|
|
901
|
+
class CalendarColors:
|
|
902
|
+
Blue = (QColor(52, 132, 207), QColor(38, 121, 199))
|
|
903
|
+
Green = (QColor(65, 243, 71), QColor(63, 235, 66))
|
|
904
|
+
Red = (QColor(243, 65, 65), QColor(228, 62, 62))
|
|
905
|
+
|
|
906
|
+
class CalendarReportWidget(QCalendarWidget):
|
|
907
|
+
def __init__(self, enabled_dates: dict[str, Union[str, None]], color: CalendarColors):
|
|
908
|
+
super().__init__()
|
|
909
|
+
|
|
910
|
+
self.enabled_dates = enabled_dates
|
|
911
|
+
self.color = color
|
|
912
|
+
|
|
913
|
+
print(enabled_dates)
|
|
914
|
+
|
|
915
|
+
def paintCell(self, painter: QPainter, rect: QRect, date: QDate):
|
|
916
|
+
super().paintCell(painter, rect, date)
|
|
917
|
+
|
|
918
|
+
date_str = date.toString(DateTimeField.date_format)
|
|
919
|
+
|
|
920
|
+
if date_str in self.enabled_dates.keys() or date == self.selectedDate():
|
|
921
|
+
if date == self.selectedDate():
|
|
922
|
+
if date_str in self.enabled_dates.keys():
|
|
923
|
+
painter.fillRect(rect, self.color[1])
|
|
924
|
+
else:
|
|
925
|
+
painter.fillRect(rect, self.palette().color(QPalette.ColorRole.Midlight))
|
|
926
|
+
elif date_str in self.enabled_dates.keys():
|
|
927
|
+
painter.fillRect(rect, self.color[0])
|
|
928
|
+
|
|
929
|
+
# if date != self.selectedDate():
|
|
930
|
+
# painter.fillRect(rect, self.color[0])
|
|
931
|
+
# elif date_str in self.enabled_dates.keys():
|
|
932
|
+
# painter.fillRect(rect, self.color[1])
|
|
933
|
+
# else:
|
|
934
|
+
# painter.fillRect(rect, self.palette().color(QPalette.ColorRole.Midlight))
|
|
935
|
+
painter.drawText(rect, Qt.AlignmentFlag.AlignCenter, str(date.day()))
|
|
936
|
+
|
|
937
|
+
def eventFilter(self, obj: QObject, event: QEvent) -> bool:
|
|
938
|
+
if obj is self and event.type() == QEvent.Type.ToolTip:
|
|
939
|
+
pos: QPoint = event.pos()
|
|
940
|
+
date = self.get_date_at_position(pos)
|
|
941
|
+
date_str = date.toString(DateTimeField.date_format)
|
|
942
|
+
|
|
943
|
+
if date_str in self.enabled_dates.keys() and self.enabled_dates[date_str] is not None:
|
|
944
|
+
print(self.enabled_dates[date_str])
|
|
945
|
+
QToolTip.showText(self.mapToGlobal(pos), self.enabled_dates[date_str], self)
|
|
946
|
+
return super().eventFilter(obj, event)
|
|
947
|
+
|
|
948
|
+
def get_date_at_position(self, pos: QPoint) -> QDate:
|
|
949
|
+
table_view: QTableView = self.findChild(QTableView)
|
|
950
|
+
if not table_view:
|
|
951
|
+
return QDate()
|
|
952
|
+
|
|
953
|
+
table_pos = table_view.mapFrom(self, pos)
|
|
954
|
+
|
|
955
|
+
index = table_view.indexAt(table_pos)
|
|
956
|
+
if not index.isValid():
|
|
957
|
+
return QDate()
|
|
958
|
+
|
|
959
|
+
return self.get_date_from_index(index.row()-1, index.column()-1)
|
|
960
|
+
|
|
961
|
+
def get_date_from_index(self, row: int, column: int) -> QDate:
|
|
962
|
+
year = self.yearShown()
|
|
963
|
+
month = self.monthShown()
|
|
964
|
+
|
|
965
|
+
first_day = QDate(year, month, 1)
|
|
966
|
+
offset = (first_day.dayOfWeek() - self.firstDayOfWeek().value) % 7
|
|
967
|
+
|
|
968
|
+
start_date = first_day.addDays(-offset)
|
|
969
|
+
|
|
970
|
+
if offset == 0:
|
|
971
|
+
start_date = start_date.addDays(-7)
|
|
972
|
+
|
|
973
|
+
return start_date.addDays(row * 7 + column)
|
|
974
|
+
|
|
975
|
+
class CalendarReport(ReportSection):
|
|
976
|
+
def __init__(self, sql_request: str, date: str, values: Optional[str] = None,
|
|
977
|
+
color: CalendarColors = CalendarColors.Blue, stretch: int = 0):
|
|
978
|
+
super().__init__(sql_request, stretch)
|
|
979
|
+
self.date = date
|
|
980
|
+
self.values = values
|
|
981
|
+
self.color = color
|
|
982
|
+
|
|
983
|
+
def create_widget(self, settings: dict[str, ReportSettingsItem]):
|
|
984
|
+
request = self.generate_sql_request(settings)
|
|
985
|
+
db_data = self.db.cur.execute(request, {k: v.data for k, v in settings.items()}).fetchall()
|
|
986
|
+
|
|
987
|
+
if self.values is not None:
|
|
988
|
+
widget = CalendarReportWidget({row[self.date]:str(row[self.values]) for row in db_data}, self.color)
|
|
989
|
+
else:
|
|
990
|
+
widget = CalendarReportWidget({row[self.date]:None for row in db_data}, self.color)
|
|
991
|
+
|
|
992
|
+
return widget
|
|
993
|
+
|
|
994
|
+
|
|
901
995
|
class ReportTab(Tab):
|
|
902
996
|
"""
|
|
903
997
|
Вкладка отчёта. Отчёт представляет собой структурированные в виде
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|