sarmat 1.2.3__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 (64) hide show
  1. sarmat-1.2.3/LICENSE +19 -0
  2. sarmat-1.2.3/PKG-INFO +122 -0
  3. sarmat-1.2.3/README.md +88 -0
  4. sarmat-1.2.3/pyproject.toml +25 -0
  5. sarmat-1.2.3/sarmat/__init__.py +3 -0
  6. sarmat-1.2.3/sarmat/core/__init__.py +5 -0
  7. sarmat-1.2.3/sarmat/core/actions/__init__.py +20 -0
  8. sarmat-1.2.3/sarmat/core/actions/bases.py +17 -0
  9. sarmat-1.2.3/sarmat/core/actions/dispatcher.py +205 -0
  10. sarmat-1.2.3/sarmat/core/actions/geo_locations.py +48 -0
  11. sarmat-1.2.3/sarmat/core/actions/traffic_management.py +302 -0
  12. sarmat-1.2.3/sarmat/core/behavior/__init__.py +24 -0
  13. sarmat-1.2.3/sarmat/core/behavior/bases.py +86 -0
  14. sarmat-1.2.3/sarmat/core/behavior/geo_locations.py +196 -0
  15. sarmat-1.2.3/sarmat/core/behavior/sarmat.py +64 -0
  16. sarmat-1.2.3/sarmat/core/behavior/traffic_management.py +632 -0
  17. sarmat-1.2.3/sarmat/core/behavior/vehicle.py +164 -0
  18. sarmat-1.2.3/sarmat/core/constants/__init__.py +38 -0
  19. sarmat-1.2.3/sarmat/core/constants/exception_constants.py +66 -0
  20. sarmat-1.2.3/sarmat/core/constants/formats.py +12 -0
  21. sarmat-1.2.3/sarmat/core/constants/sarmat_constants.py +328 -0
  22. sarmat-1.2.3/sarmat/core/context/__init__.py +0 -0
  23. sarmat-1.2.3/sarmat/core/context/containers/__init__.py +43 -0
  24. sarmat-1.2.3/sarmat/core/context/containers/dispatcher_containers.py +86 -0
  25. sarmat-1.2.3/sarmat/core/context/containers/geo_containers.py +47 -0
  26. sarmat-1.2.3/sarmat/core/context/containers/sarmat_containers.py +75 -0
  27. sarmat-1.2.3/sarmat/core/context/containers/traffic_management_containers.py +111 -0
  28. sarmat-1.2.3/sarmat/core/context/containers/vehicle_containers.py +57 -0
  29. sarmat-1.2.3/sarmat/core/context/models/__init__.py +40 -0
  30. sarmat-1.2.3/sarmat/core/context/models/dispatcher_models.py +126 -0
  31. sarmat-1.2.3/sarmat/core/context/models/geo_models.py +131 -0
  32. sarmat-1.2.3/sarmat/core/context/models/sarmat_models.py +120 -0
  33. sarmat-1.2.3/sarmat/core/context/models/traffic_management_models.py +306 -0
  34. sarmat-1.2.3/sarmat/core/context/models/vehicle_models.py +120 -0
  35. sarmat-1.2.3/sarmat/core/exceptions/__init__.py +13 -0
  36. sarmat-1.2.3/sarmat/core/exceptions/exceptions.py +62 -0
  37. sarmat-1.2.3/sarmat/core/exceptions/sarmat_exceptions.py +30 -0
  38. sarmat-1.2.3/sarmat/core/factory/__init__.py +26 -0
  39. sarmat-1.2.3/sarmat/core/factory/base_creator.py +178 -0
  40. sarmat-1.2.3/sarmat/core/factory/geo_creator.py +52 -0
  41. sarmat-1.2.3/sarmat/core/factory/traffic_manager_creator.py +214 -0
  42. sarmat-1.2.3/sarmat/core/factory/vehicle_creator.py +81 -0
  43. sarmat-1.2.3/sarmat/core/verification/__init__.py +33 -0
  44. sarmat-1.2.3/sarmat/core/verification/base_verifications.py +48 -0
  45. sarmat-1.2.3/sarmat/core/verification/customize_verifications.py +17 -0
  46. sarmat-1.2.3/sarmat/core/verification/geo_verifications.py +68 -0
  47. sarmat-1.2.3/sarmat/core/verification/traffic_management_verifications.py +89 -0
  48. sarmat-1.2.3/sarmat/core/verification/vehicle_verifications.py +54 -0
  49. sarmat-1.2.3/sarmat/tools/__init__.py +5 -0
  50. sarmat-1.2.3/sarmat/tools/fare_calculation.py +324 -0
  51. sarmat-1.2.3/sarmat/tools/fare_containers.py +56 -0
  52. sarmat-1.2.3/sarmat/tools/geo_tools.py +36 -0
  53. sarmat-1.2.3/sarmat/tools/json_encoder.py +66 -0
  54. sarmat-1.2.3/sarmat.egg-info/PKG-INFO +122 -0
  55. sarmat-1.2.3/sarmat.egg-info/SOURCES.txt +63 -0
  56. sarmat-1.2.3/sarmat.egg-info/dependency_links.txt +1 -0
  57. sarmat-1.2.3/sarmat.egg-info/requires.txt +1 -0
  58. sarmat-1.2.3/sarmat.egg-info/top_level.txt +1 -0
  59. sarmat-1.2.3/setup.cfg +23 -0
  60. sarmat-1.2.3/setup.py +27 -0
  61. sarmat-1.2.3/tests/test_constants.py +202 -0
  62. sarmat-1.2.3/tests/test_fare.py +35 -0
  63. sarmat-1.2.3/tests/test_fare_calculation.py +47 -0
  64. sarmat-1.2.3/tests/test_fare_strategy.py +116 -0
sarmat-1.2.3/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2018 The Python Packaging Authority
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
sarmat-1.2.3/PKG-INFO ADDED
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.1
2
+ Name: sarmat
3
+ Version: 1.2.3
4
+ Summary: Sarmat
5
+ Home-page:
6
+ Author: Artel
7
+ Author-email: Artel <artel61@gmail.com>
8
+ License: Copyright (c) 2018 The Python Packaging Authority
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Classifier: Programming Language :: Python :: 3
29
+ Classifier: License :: OSI Approved :: MIT License
30
+ Classifier: Operating System :: OS Independent
31
+ Requires-Python: >=3.8
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+
35
+ # Sarmat.
36
+
37
+ Библиотека для построения решений в сфере пассажирского транспорта.
38
+
39
+ Основу работы библиотеки составляют объекты для построения рейсов
40
+ и шаблонов для них, выполнения диспетчерских операций,
41
+ и управления автотранспортом.
42
+
43
+ ## Состав библиотеки
44
+
45
+ Библиотека состоит из набора тематических модулей, у каждого из которых своя область
46
+ применения:
47
+
48
+ * Сущности для описания справочников
49
+ * Сущности для построения рейсов и маршрутов
50
+ * Сущности для описания работы транспортной компании.
51
+
52
+ ## Композиция объектов
53
+
54
+ Каждый из тематических объектов представлен в виде композиции классов.
55
+
56
+ ### Модели и контейнеры
57
+
58
+ Модель содержит набор атрибутов, присущих объекту класса,
59
+ а также методы создания модели на основе контейнера. Реализована вложенность
60
+ моделей. В том числе для описания иерархической модели справочников. Каждая модель
61
+ является фабрикой для создания объектов своего типа. Фабричный метод принимает
62
+ на вход аргумент, который имеет тип соответствующего контейнера.
63
+ Контейнеры также могут быть вложенными.
64
+
65
+ Контейнеры повторяют набор атрибутов, описанных в модели. Контейнеры предназначены
66
+ для получения атрибутов извне и правильного создания модели
67
+ на основе полученных данных. Контейнеры написаны на основе классов `pydantic`.
68
+
69
+ ### Верификация объектов
70
+
71
+ Основные правила верификации объектов описаны в контейнерах. Все случаи проверки,
72
+ которые являются частью бизнес-логики, описаны в специальных классах верификаторах.
73
+ Эти классы задействуются перед созданием модели из контейнера. Верификацию
74
+ проходят **контейнеры**. Объекты верификации содержат рбязательный метод `verify`,
75
+ в котором реализована логика проверки. Верификаторы могут быть вложенными. В этом
76
+ случае процесс проверки будет идти от дочернего верификатора к родительскому.
77
+ Метод верификации не возвращает значений, но возбуздает исключения
78
+ в случае нарушения правил проверки.
79
+
80
+ Базовый верификатор проверяет на непустоту указанных атрибутов. Есть возможность
81
+ создать верификатор на основе кастомного класса. В нем проверка происходит
82
+ на основе встроенного словаря. Ключами словаря могут выступать строковые константы,
83
+ а значениями - вызываемые объекты.
84
+
85
+ ### Поведение объектов
86
+
87
+ Поведение объектов описано в поведенческих классах. Там реализован набор
88
+ простейших операций, упрощающих процесс прикладной разработки. Поведенческие
89
+ классы позволяют проводить сравнение двух объектов между собой (`==`, `!=`),
90
+ выполнять операции проверки на неравенство (`>`, `<`, `>=`, `<=`).
91
+ Для объектов, содержащих другие объекты, реализована проверка на вхождение
92
+ во множество (`in`). За это ответственны поведенческие классы сравнения. Базовым
93
+ поведенческим классом является класс `BhNoAction`, который можно использовать
94
+ для переопределения или дополнения модели поведения для того или иного класса
95
+ в рамках той или иной роли приложения.
96
+ К примеру, сотрудник с правами оператора системы может создавать рейсы и
97
+ проводить с ними прочие операции редактирования. Другой сотрудник с правами
98
+ диспетчера может обрабатывать созданные рейсы, но не может их создавать. Для
99
+ описания этих различных моделей поведения необходимо создать два поведенческих класса
100
+ `Actor` и `Dispatcher`, первый из которых будет содержать методы CRUD для работы
101
+ с объектом, а втрой будет иметь набор методов работы с созданныим рейсами. Оба класса
102
+ регистрируются в фабрике классов под своими псевдонимами. Потом нужный псевдоним
103
+ указывается при вызове фабрики, и для каждой модели ищется соответствующий класс.
104
+ Если необходимо совместить для пользователя полномочия, то соответствующие
105
+ псевдонимы склеиваются. В качестве разделителя используется точка.
106
+
107
+ ### Действия с объектами
108
+
109
+ Для объектов реализованы простейшие операции. Такие, как, например, копирование
110
+ объекта. Реализованы специфические операции для конкретных объектов.
111
+
112
+ ## Сборка объектов
113
+
114
+ Сборкой объектов занимаются фабрики классов. Каждая тематическая фабрика обладает
115
+ набором методов, каждый из которых создает объект своего типа. Сборка объектов
116
+ производится вызовом `type` с последующей инициализацией полученного класса при
117
+ помощи данных, которые передаются в контейнере. В фабрике перечисляются
118
+ родительские классы, а также указываются дополнительные атрибуты для будущего
119
+ объекта: в атрибуте `controller` передается экземпляр фабрики для последующего
120
+ использования при создании объектов во время выполнения бизнесс процессов.
121
+ Также передается набор тегов доступа, которые были определены пользователю
122
+ изначально.
sarmat-1.2.3/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Sarmat.
2
+
3
+ Библиотека для построения решений в сфере пассажирского транспорта.
4
+
5
+ Основу работы библиотеки составляют объекты для построения рейсов
6
+ и шаблонов для них, выполнения диспетчерских операций,
7
+ и управления автотранспортом.
8
+
9
+ ## Состав библиотеки
10
+
11
+ Библиотека состоит из набора тематических модулей, у каждого из которых своя область
12
+ применения:
13
+
14
+ * Сущности для описания справочников
15
+ * Сущности для построения рейсов и маршрутов
16
+ * Сущности для описания работы транспортной компании.
17
+
18
+ ## Композиция объектов
19
+
20
+ Каждый из тематических объектов представлен в виде композиции классов.
21
+
22
+ ### Модели и контейнеры
23
+
24
+ Модель содержит набор атрибутов, присущих объекту класса,
25
+ а также методы создания модели на основе контейнера. Реализована вложенность
26
+ моделей. В том числе для описания иерархической модели справочников. Каждая модель
27
+ является фабрикой для создания объектов своего типа. Фабричный метод принимает
28
+ на вход аргумент, который имеет тип соответствующего контейнера.
29
+ Контейнеры также могут быть вложенными.
30
+
31
+ Контейнеры повторяют набор атрибутов, описанных в модели. Контейнеры предназначены
32
+ для получения атрибутов извне и правильного создания модели
33
+ на основе полученных данных. Контейнеры написаны на основе классов `pydantic`.
34
+
35
+ ### Верификация объектов
36
+
37
+ Основные правила верификации объектов описаны в контейнерах. Все случаи проверки,
38
+ которые являются частью бизнес-логики, описаны в специальных классах верификаторах.
39
+ Эти классы задействуются перед созданием модели из контейнера. Верификацию
40
+ проходят **контейнеры**. Объекты верификации содержат рбязательный метод `verify`,
41
+ в котором реализована логика проверки. Верификаторы могут быть вложенными. В этом
42
+ случае процесс проверки будет идти от дочернего верификатора к родительскому.
43
+ Метод верификации не возвращает значений, но возбуздает исключения
44
+ в случае нарушения правил проверки.
45
+
46
+ Базовый верификатор проверяет на непустоту указанных атрибутов. Есть возможность
47
+ создать верификатор на основе кастомного класса. В нем проверка происходит
48
+ на основе встроенного словаря. Ключами словаря могут выступать строковые константы,
49
+ а значениями - вызываемые объекты.
50
+
51
+ ### Поведение объектов
52
+
53
+ Поведение объектов описано в поведенческих классах. Там реализован набор
54
+ простейших операций, упрощающих процесс прикладной разработки. Поведенческие
55
+ классы позволяют проводить сравнение двух объектов между собой (`==`, `!=`),
56
+ выполнять операции проверки на неравенство (`>`, `<`, `>=`, `<=`).
57
+ Для объектов, содержащих другие объекты, реализована проверка на вхождение
58
+ во множество (`in`). За это ответственны поведенческие классы сравнения. Базовым
59
+ поведенческим классом является класс `BhNoAction`, который можно использовать
60
+ для переопределения или дополнения модели поведения для того или иного класса
61
+ в рамках той или иной роли приложения.
62
+ К примеру, сотрудник с правами оператора системы может создавать рейсы и
63
+ проводить с ними прочие операции редактирования. Другой сотрудник с правами
64
+ диспетчера может обрабатывать созданные рейсы, но не может их создавать. Для
65
+ описания этих различных моделей поведения необходимо создать два поведенческих класса
66
+ `Actor` и `Dispatcher`, первый из которых будет содержать методы CRUD для работы
67
+ с объектом, а втрой будет иметь набор методов работы с созданныим рейсами. Оба класса
68
+ регистрируются в фабрике классов под своими псевдонимами. Потом нужный псевдоним
69
+ указывается при вызове фабрики, и для каждой модели ищется соответствующий класс.
70
+ Если необходимо совместить для пользователя полномочия, то соответствующие
71
+ псевдонимы склеиваются. В качестве разделителя используется точка.
72
+
73
+ ### Действия с объектами
74
+
75
+ Для объектов реализованы простейшие операции. Такие, как, например, копирование
76
+ объекта. Реализованы специфические операции для конкретных объектов.
77
+
78
+ ## Сборка объектов
79
+
80
+ Сборкой объектов занимаются фабрики классов. Каждая тематическая фабрика обладает
81
+ набором методов, каждый из которых создает объект своего типа. Сборка объектов
82
+ производится вызовом `type` с последующей инициализацией полученного класса при
83
+ помощи данных, которые передаются в контейнере. В фабрике перечисляются
84
+ родительские классы, а также указываются дополнительные атрибуты для будущего
85
+ объекта: в атрибуте `controller` передается экземпляр фабрики для последующего
86
+ использования при создании объектов во время выполнения бизнесс процессов.
87
+ Также передается набор тегов доступа, которые были определены пользователю
88
+ изначально.
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "pydantic"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sarmat"
7
+ version = "1.2.3"
8
+ authors = [
9
+ { name="Artel", email="artel61@gmail.com" },
10
+ ]
11
+ description = "Sarmat"
12
+ readme = "README.md"
13
+ license = { file="LICENSE" }
14
+ requires-python = ">=3.8"
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+
21
+ [tool.pytest.ini_options]
22
+ minversion = "6.0"
23
+ testpaths = [
24
+ "tests",
25
+ ]
@@ -0,0 +1,3 @@
1
+ VERSION = "1.2.3"
2
+
3
+ __version__ = VERSION
@@ -0,0 +1,5 @@
1
+ """
2
+ Sarmat.
3
+
4
+ Ядро пакета.
5
+ """
@@ -0,0 +1,20 @@
1
+ """
2
+ Sarmat.
3
+
4
+ Описание действий с объектами.
5
+ """
6
+ __all__ = (
7
+ "AGeoLocationMixin", "ADestinationPointMixin", "AStationMixin", "ARouteMixin", "AJourneyMixin",
8
+ "AJourneyBunchMixin",
9
+ )
10
+
11
+ from .geo_locations import (
12
+ ADestinationPointMixin,
13
+ AGeoLocationMixin,
14
+ )
15
+ from .traffic_management import (
16
+ AJourneyMixin,
17
+ AJourneyBunchMixin,
18
+ ARouteMixin,
19
+ AStationMixin,
20
+ )
@@ -0,0 +1,17 @@
1
+ """
2
+ Sarmat.
3
+
4
+ Описание действий с объектами.
5
+
6
+ Базовые классы.
7
+ """
8
+
9
+
10
+ class ActionMixin:
11
+ """Базовый класс-примесь для описания работы с объектами"""
12
+
13
+ def __init__(self, **kwargs):
14
+ super().__init__(**kwargs)
15
+
16
+ def copy(self):
17
+ raise NotImplementedError
@@ -0,0 +1,205 @@
1
+ """
2
+ Sarmat.
3
+
4
+ Описание поведения объектов.
5
+
6
+ Поведение объектов в режиме работы диспетчера.
7
+ """
8
+ from abc import ABC, abstractmethod
9
+ from datetime import date, datetime, tzinfo
10
+ from typing import Dict, Optional, List, Union
11
+ from uuid import uuid4
12
+
13
+ from sarmat.core.constants import JourneyClass, JourneyState
14
+ from sarmat.core.context.models import (
15
+ PermitModel,
16
+ RouteItemModel,
17
+ StationModel,
18
+ JourneyProgressModel,
19
+ JourneyScheduleModel,
20
+ JourneyModel,
21
+ )
22
+ from sarmat.core.exceptions.sarmat_exceptions import ImpossibleOperationError
23
+
24
+ from sarmat.core.behavior.traffic_management import BhJourney
25
+
26
+
27
+ class Journey(BhJourney):
28
+ """Поведение объекта Рейс"""
29
+
30
+ def activate(
31
+ self,
32
+ start_date: date,
33
+ permit: PermitModel,
34
+ ) -> Dict[str, Union[JourneyProgressModel, List[JourneyScheduleModel]]]:
35
+ """
36
+ Активизация рейса (выписка рейсовой ведомости, создание расписания по рейсу)
37
+ Args:
38
+ start_date: дата начала выполнения рейса (отправление из начальной точки)
39
+ permit: путевой лист
40
+
41
+ Returns:
42
+ рейсовая ведомость
43
+ список активных пунктов маршрута
44
+
45
+ """
46
+ # атрибуты текущего рейса и список активных станций, через которые проходит рейс
47
+ this_journey = JourneyModel.from_container(self.raw()) # type: ignore
48
+ journey_stations = [item for item in self.get_journey_schedule(start_date) if item.station is not None]
49
+ first_station, *middleware_stations, last_station = journey_stations
50
+
51
+ journey_progress = JourneyProgressModel( # Атрибуты рейсовой ведомости
52
+ uid=str(uuid4()), # идентификатор ведомости
53
+ depart_date=start_date, # дата отправления в рейс
54
+ journey=this_journey, # рейс
55
+ permit=permit, # путевой лист
56
+ )
57
+
58
+ journey_schedule = [
59
+ JourneyScheduleModel(
60
+ uid=str(uuid4()), # идентификатор строки
61
+ journey_progress=journey_progress, # рейсовая ведомость
62
+ journey_class=JourneyClass.BASE, # класс рейса (формирующийся)
63
+ station=first_station.station, # станция
64
+ point=first_station.point, # пункт прохождения маршрута
65
+ state=JourneyState.READY, # состояние рейса
66
+ plan_depart=first_station.depart, # плановое время отправления
67
+ platform='', # платформа
68
+ comment='', # комментарий к текущему пункту
69
+ )
70
+ ]
71
+
72
+ journey_schedule += [
73
+ JourneyScheduleModel(
74
+ uid=str(uuid4()), # идентификатор строки
75
+ journey_progress=journey_progress, # рейсовая ведомость
76
+ journey_class=JourneyClass.TRANSIT, # класс рейса (формирующийся)
77
+ station=item.station, # станция
78
+ point=item.point, # пункт прохождения маршрута
79
+ state=JourneyState.READY, # состояние рейса
80
+ plan_arrive=item.arrive, # плановое время прибытия
81
+ plan_depart=item.depart, # плановое время отправления
82
+ platform='', # платформа
83
+ comment='', # комментарий к текущему пункту
84
+ )
85
+ for item in middleware_stations
86
+ ]
87
+
88
+ journey_schedule.append(
89
+ JourneyScheduleModel(
90
+ uid=str(uuid4()), # идентификатор строки
91
+ journey_progress=journey_progress, # рейсовая ведомость
92
+ journey_class=JourneyClass.ARRIVING, # класс рейса (формирующийся)
93
+ station=last_station.station, # станция
94
+ point=last_station.point, # пункт прохождения маршрута
95
+ state=JourneyState.READY, # состояние рейса
96
+ plan_arrive=last_station.arrive, # плановое время прибытия
97
+ platform='', # платформа
98
+ comment='', # комментарий к текущему пункту
99
+ )
100
+ )
101
+
102
+ for idx, item in enumerate(journey_schedule):
103
+ journey_schedule[idx].last_items = journey_schedule[idx+1:]
104
+
105
+ return {
106
+ 'JourneyProgress': journey_progress,
107
+ 'JourneyScheduleStructure': journey_schedule,
108
+ }
109
+
110
+
111
+ class JourneySchedule:
112
+ """Поведение объекта Рейсовая ведомость в активном расписании"""
113
+
114
+ journey_class: JourneyClass
115
+ state: JourneyState
116
+ fact_arrive: datetime
117
+ fact_depart: datetime
118
+ permit: Optional[PermitModel]
119
+ platform: str
120
+ comment: str
121
+ last_items: List['JourneySchedule']
122
+ current_item: RouteItemModel
123
+
124
+ def make_departure(self, time_zone: Optional[tzinfo] = None) -> None:
125
+ """Операция отправления на текущем пункте"""
126
+
127
+ if self.journey_class == JourneyClass.ARRIVING:
128
+ raise ImpossibleOperationError("На последнем пункте маршрута операция отправления не выполняется")
129
+
130
+ self.state = JourneyState.DEPARTED
131
+ self.fact_depart = datetime.now(time_zone)
132
+
133
+ def make_registration(self,
134
+ permit: Optional[PermitModel] = None,
135
+ platform: Optional[str] = None,
136
+ comments: Optional[str] = None) -> None:
137
+ """
138
+ Операция по регистрации рейса. Заполнение реквизитов
139
+ Args:
140
+ permit: путевой лист
141
+ platform: номер платформы
142
+ comments: комментарии диспетчера
143
+ """
144
+
145
+ if permit and (permit != self.permit):
146
+ self.permit = permit
147
+
148
+ if platform and platform != self.platform:
149
+ self.platform = platform
150
+
151
+ # NOTE: комментарий дозволяется затереть
152
+ if comments != self.comment:
153
+ self.comment = comments or ''
154
+
155
+ def make_arrival(self, time_zone: Optional[tzinfo] = None) -> None:
156
+ """Операция прибытия на текущем пункте"""
157
+ is_last = self.journey_class == JourneyClass.ARRIVING
158
+ operational_time = datetime.now(time_zone)
159
+
160
+ new_state = JourneyState.ARRIVED if is_last else JourneyState.ON_REGISTRATION
161
+ self.state = new_state
162
+ self.fact_arrive = operational_time
163
+
164
+ def cancel_journey(self) -> None:
165
+ """Отмена рейса"""
166
+ self._set_state_for_items_chain(JourneyState.CANCELLED)
167
+
168
+ def close_journey(self) -> None:
169
+ """Закрытие рейса"""
170
+ self._set_state_for_items_chain(JourneyState.CLOSED)
171
+
172
+ def break_journey(self) -> None:
173
+ """Отметка о срыве"""
174
+ self._set_state_for_items_chain(JourneyState.DISRUPTED)
175
+
176
+ @property
177
+ def current_station(self) -> Optional[StationModel]:
178
+ """Текущий пункт прохождения рейса"""
179
+ return self.current_item.station if self.current_item else None
180
+
181
+ def _set_state_for_items_chain(self, state: JourneyState) -> None:
182
+ """Назначение состояния текущему элементу и всем последующим"""
183
+ self.state = state
184
+ for item in self.last_items:
185
+ item.state = state
186
+
187
+
188
+ class JourneyHook(ABC):
189
+ """Поведение объекта Рейсовая Ведомость"""
190
+
191
+ @abstractmethod
192
+ def lock_register(self):
193
+ """Блокировка ведомости"""
194
+
195
+ @abstractmethod
196
+ def unlock_register(self):
197
+ """Снятие блокировки с ведомости"""
198
+
199
+ @abstractmethod
200
+ def register_place(self):
201
+ """Регистрация места на ведомости"""
202
+
203
+ @abstractmethod
204
+ def unregister_place(self):
205
+ """Отмена регистрации места на ведомости"""
@@ -0,0 +1,48 @@
1
+ """
2
+ Sarmat.
3
+
4
+ Описание действий с объектами.
5
+
6
+ Классы для работы с объектами гео локации.
7
+ """
8
+ from sarmat.core.constants import LocationType, SettlementType
9
+
10
+ from .bases import ActionMixin
11
+
12
+
13
+ class AGeoLocationMixin(ActionMixin):
14
+ """Действия с объектами гео локации"""
15
+
16
+ name: str
17
+ latin_name: str
18
+ mapping_data: dict
19
+ tags: str
20
+ location_type: LocationType
21
+ parent: object
22
+
23
+ def copy(self):
24
+ return self.__class__(
25
+ id=0,
26
+ name=f"Копия {self.name}",
27
+ location_type=self.location_type,
28
+ latin_name=f"Copy of {self.latin_name}" if self.latin_name else "",
29
+ mapping_data=self.mapping_data,
30
+ tags=self.tags,
31
+ parent=self.parent,
32
+ )
33
+
34
+
35
+ class ADestinationPointMixin(ActionMixin):
36
+ """Действия с пунктами назначения"""
37
+
38
+ name: str
39
+ state: object
40
+ point_type: SettlementType
41
+
42
+ def copy(self):
43
+ return self.__class__(
44
+ id=0,
45
+ name=f"Копия {self.name}",
46
+ state=self.state,
47
+ point_type=self.point_type,
48
+ )