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.
Files changed (28) hide show
  1. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/PKG-INFO +2 -2
  2. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/README.md +1 -1
  3. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/pyproject.toml +1 -1
  4. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/__init__.py +1 -1
  5. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/reports/__init__.py +4 -1
  6. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/reports/report.py +98 -4
  7. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/.github/workflows/python-publish.yml +0 -0
  8. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/.gitignore +0 -0
  9. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/LICENSE +0 -0
  10. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/apps/development360/development360.py +0 -0
  11. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/apps/technoholding/technoholding.py +0 -0
  12. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/apps/vunderkind/vunderkind.py +0 -0
  13. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/__init__.py +0 -0
  14. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/app.py +0 -0
  15. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/db.py +0 -0
  16. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/styles.qss +0 -0
  17. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/app/themes.py +0 -0
  18. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/fields/__init__.py +0 -0
  19. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/fields/combo_box_items.py +0 -0
  20. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/fields/field.py +0 -0
  21. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/processes/__init__.py +0 -0
  22. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/processes/process.py +0 -0
  23. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/processes/task.py +0 -0
  24. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/__init__.py +0 -0
  25. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/group.py +0 -0
  26. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/tab.py +0 -0
  27. {bpappbuilder-0.2.0 → bpappbuilder-0.3.0}/src/bpappbuilder/tabs/table.py +0 -0
  28. {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.2.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
  - [ ] Сделать автоматическое обновление вкладок
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bpappbuilder"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  authors = [
9
9
  { name="AlexK-1" }
10
10
  ]
@@ -5,4 +5,4 @@ import bpappbuilder.tabs
5
5
  import bpappbuilder.processes
6
6
 
7
7
  # __all__ = ["App", "Fields", "Reports", "Tabs"]
8
- __version__ = "0.2.0"
8
+ __version__ = "0.3.0"
@@ -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", "ReportTab"]
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