zou 0.20.61__py3-none-any.whl → 0.20.63__py3-none-any.whl

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 (58) hide show
  1. zou/__init__.py +1 -1
  2. zou/app/api.py +2 -0
  3. zou/app/blueprints/crud/__init__.py +25 -1
  4. zou/app/blueprints/crud/hardware_item.py +12 -0
  5. zou/app/blueprints/crud/notification.py +0 -4
  6. zou/app/blueprints/crud/production_schedule_version.py +114 -0
  7. zou/app/blueprints/departments/__init__.py +35 -0
  8. zou/app/blueprints/departments/resources.py +262 -0
  9. zou/app/blueprints/index/resources.py +2 -9
  10. zou/app/blueprints/persons/resources.py +1 -3
  11. zou/app/blueprints/projects/__init__.py +20 -0
  12. zou/app/blueprints/projects/resources.py +200 -0
  13. zou/app/blueprints/tasks/resources.py +5 -2
  14. zou/app/blueprints/user/resources.py +1 -3
  15. zou/app/models/base.py +15 -4
  16. zou/app/models/department.py +62 -0
  17. zou/app/models/entity.py +3 -3
  18. zou/app/models/hardware_item.py +15 -0
  19. zou/app/models/person.py +1 -1
  20. zou/app/models/production_schedule_version.py +81 -0
  21. zou/app/models/project.py +17 -6
  22. zou/app/models/software.py +5 -1
  23. zou/app/models/task.py +7 -10
  24. zou/app/services/assets_service.py +5 -6
  25. zou/app/services/concepts_service.py +3 -4
  26. zou/app/services/deletion_service.py +10 -18
  27. zou/app/services/departments_service.py +153 -0
  28. zou/app/services/edits_service.py +3 -4
  29. zou/app/services/entities_service.py +5 -6
  30. zou/app/services/exception.py +8 -0
  31. zou/app/services/file_tree_service.py +2 -2
  32. zou/app/services/preview_files_service.py +6 -2
  33. zou/app/services/schedule_service.py +243 -1
  34. zou/app/services/shots_service.py +3 -4
  35. zou/app/services/tasks_service.py +5 -1
  36. zou/app/services/user_service.py +57 -23
  37. zou/migrations/alembic.ini +1 -1
  38. zou/migrations/versions/0bd1e89f2a6f_add_productionscheduleversiontasklink_uc.py +58 -0
  39. zou/migrations/versions/26f96f65cfa3_add_productionversionschedule_uc.py +40 -0
  40. zou/migrations/versions/3d8e68dffeee_fix_task_person_link.py +56 -0
  41. zou/migrations/versions/4368137b44e1_productionscheduleversion_add_on_delete_.py +188 -0
  42. zou/migrations/versions/4bd9bfb73f11_add_fields_to_the_software_table.py +49 -0
  43. zou/migrations/versions/5f715f2b6348_add_new_table_productionscheduleversion.py +128 -0
  44. zou/migrations/versions/7a16258f2fab_add_currency_field_to_budgets.py +2 -4
  45. zou/migrations/versions/9683bd840dee_add_archived_field_to_software.py +33 -0
  46. zou/migrations/versions/9af2df17a9d5_add_hardware_table.py +48 -0
  47. zou/migrations/versions/ce7f46f445dc_add_column_estimation_for_.py +37 -0
  48. zou/migrations/versions/d5665dca188b_add_version_field_to_software.py +35 -0
  49. zou/migrations/versions/d97f2730bf7b_add_.py +101 -0
  50. zou/migrations/versions/dde6be40f54f_add_departement_links_tables_for_.py +151 -0
  51. zou/migrations/versions/e4b48ca33539_add_project_production_schedule_version_.py +56 -0
  52. zou/migrations/versions/e8bc24998b34_remove_on_delete_cascade_for_.py +59 -0
  53. {zou-0.20.61.dist-info → zou-0.20.63.dist-info}/METADATA +3 -3
  54. {zou-0.20.61.dist-info → zou-0.20.63.dist-info}/RECORD +58 -37
  55. {zou-0.20.61.dist-info → zou-0.20.63.dist-info}/WHEEL +0 -0
  56. {zou-0.20.61.dist-info → zou-0.20.63.dist-info}/entry_points.txt +0 -0
  57. {zou-0.20.61.dist-info → zou-0.20.63.dist-info}/licenses/LICENSE +0 -0
  58. {zou-0.20.61.dist-info → zou-0.20.63.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ from zou.app.models.entity import Entity
7
7
  from zou.app.models.entity_type import EntityType
8
8
  from zou.app.models.notification import Notification
9
9
  from zou.app.models.person import Person
10
- from zou.app.models.project import Project
10
+ from zou.app.models.project import Project, ProjectPersonLink
11
11
  from zou.app.models.project_status import ProjectStatus
12
12
  from zou.app.models.subscription import Subscription
13
13
  from zou.app.models.search_filter import SearchFilter
@@ -15,6 +15,7 @@ from zou.app.models.search_filter_group import SearchFilterGroup
15
15
  from zou.app.models.task import Task
16
16
  from zou.app.models.task_type import TaskType
17
17
 
18
+
18
19
  from zou.app.services import (
19
20
  assets_service,
20
21
  custom_actions_service,
@@ -35,7 +36,7 @@ from zou.app.services.exception import (
35
36
  NotificationNotFoundException,
36
37
  WrongParameterException,
37
38
  )
38
- from zou.app.utils import cache, fields, permissions
39
+ from zou.app.utils import cache, fields, permissions, events
39
40
 
40
41
 
41
42
  def clear_filter_cache(user_id=None):
@@ -77,7 +78,8 @@ def build_open_project_filter():
77
78
  """
78
79
  Query filter for project to retrieve only open projects.
79
80
  """
80
- return ProjectStatus.name.in_(("Active", "open", "Open"))
81
+ open_status = projects_service.get_open_status()
82
+ return Project.project_status_id == open_status["id"]
81
83
 
82
84
 
83
85
  def build_related_projects_filter():
@@ -85,15 +87,8 @@ def build_related_projects_filter():
85
87
  Query filter for project to retrieve open projects of which the user
86
88
  is part of the team.
87
89
  """
88
- projects = (
89
- Project.query.join(
90
- ProjectStatus, Project.project_status_id == ProjectStatus.id
91
- )
92
- .filter(build_team_filter())
93
- .filter(build_open_project_filter())
94
- .all()
95
- )
96
- project_ids = [project.id for project in projects]
90
+ projects = related_projects()
91
+ project_ids = [project["id"] for project in projects]
97
92
  if len(project_ids) > 0:
98
93
  return Project.id.in_(project_ids)
99
94
  else:
@@ -103,16 +98,30 @@ def build_related_projects_filter():
103
98
  def related_projects():
104
99
  """
105
100
  Return all projects related to current user: open projects of which the user
106
- is part of the team.
101
+ is part of the team as dicts.
102
+ """
103
+ persons_service.get_current_user()
104
+ projects = related_projects_raw()
105
+ return Project.serialize_list(projects)
106
+
107
+
108
+ def related_projects_raw():
107
109
  """
110
+ Return all projects related to current user: open projects of which the user
111
+ is part of the team as models.
112
+ """
113
+ current_user = persons_service.get_current_user()
108
114
  projects = (
109
- Project.query.join(Task)
110
- .join(ProjectStatus, Project.project_status_id == ProjectStatus.id)
111
- .filter(build_team_filter())
115
+ Project.query.join(
116
+ ProjectStatus, Project.project_status_id == ProjectStatus.id
117
+ )
118
+ .join(ProjectPersonLink, Project.id == ProjectPersonLink.project_id)
119
+ .filter(ProjectPersonLink.person_id == current_user["id"])
112
120
  .filter(build_open_project_filter())
121
+ .distinct()
113
122
  .all()
114
123
  )
115
- return Project.serialize_list(projects)
124
+ return projects
116
125
 
117
126
 
118
127
  def get_todos():
@@ -328,7 +337,11 @@ def get_open_projects(name=None):
328
337
  query = query.filter(Project.name == name)
329
338
 
330
339
  if not permissions.has_admin_permissions():
331
- query = query.filter(build_team_filter())
340
+ current_user = persons_service.get_current_user()
341
+ query = query.join(
342
+ ProjectPersonLink, Project.id == ProjectPersonLink.project_id
343
+ )
344
+ query = query.filter(ProjectPersonLink.person_id == current_user["id"])
332
345
 
333
346
  for_client = False
334
347
  vendor_departments = None
@@ -353,11 +366,16 @@ def get_open_project_ids():
353
366
 
354
367
  def get_projects(name=None):
355
368
  """
356
- Get all projects for which current user has a task assigned.
369
+ Get all projects for which current user is part of the team.
357
370
  """
358
- query = Project.query.join(
359
- ProjectStatus, Project.project_status_id == ProjectStatus.id
360
- ).filter(build_team_filter())
371
+ current_user = persons_service.get_current_user()
372
+ query = (
373
+ Project.query.join(
374
+ ProjectStatus, Project.project_status_id == ProjectStatus.id
375
+ )
376
+ .join(ProjectPersonLink, Project.id == ProjectPersonLink.project_id)
377
+ .filter(ProjectPersonLink.person_id == current_user["id"])
378
+ )
361
379
 
362
380
  if name is not None:
363
381
  query = query.filter(Project.name == name)
@@ -1316,6 +1334,22 @@ def update_notification(notification_id, read):
1316
1334
  id=notification_id, person_id=current_user["id"]
1317
1335
  )
1318
1336
  notification.update({"read": read})
1337
+ if read:
1338
+ events.emit(
1339
+ "notification:read",
1340
+ {
1341
+ "person_id": current_user["id"],
1342
+ "notification_id": notification_id,
1343
+ },
1344
+ )
1345
+ else:
1346
+ events.emit(
1347
+ "notification:unread",
1348
+ {
1349
+ "person_id": current_user["id"],
1350
+ "notification_id": notification_id,
1351
+ },
1352
+ )
1319
1353
  return notification.serialize()
1320
1354
 
1321
1355
 
@@ -1513,7 +1547,7 @@ def mark_notifications_as_read():
1513
1547
 
1514
1548
  db.session.execute(update_stmt)
1515
1549
  db.session.commit()
1516
-
1550
+ events.emit("notification:all-read", {"person_id": current_user["id"]})
1517
1551
  return True
1518
1552
 
1519
1553
 
@@ -30,7 +30,7 @@ handlers =
30
30
  qualname = sqlalchemy.engine
31
31
 
32
32
  [logger_alembic]
33
- level = WARN
33
+ level = INFO
34
34
  handlers =
35
35
  qualname = alembic
36
36
 
@@ -0,0 +1,58 @@
1
+ """Add ProductionScheduleVersionTaskLink uc
2
+
3
+ Revision ID: 0bd1e89f2a6f
4
+ Revises: e4b48ca33539
5
+ Create Date: 2025-07-22 17:13:16.680191
6
+
7
+ """
8
+
9
+ from alembic import op
10
+ import sqlalchemy as sa
11
+
12
+
13
+ # revision identifiers, used by Alembic.
14
+ revision = "0bd1e89f2a6f"
15
+ down_revision = "e4b48ca33539"
16
+ branch_labels = None
17
+ depends_on = None
18
+
19
+
20
+ def upgrade():
21
+ # ### commands auto generated by Alembic - please adjust! ###
22
+ with op.batch_alter_table(
23
+ "production_schedule_version_task_link", schema=None
24
+ ) as batch_op:
25
+ batch_op.alter_column(
26
+ "production_schedule_version_id",
27
+ existing_type=sa.UUID(),
28
+ nullable=False,
29
+ )
30
+ batch_op.alter_column(
31
+ "task_id", existing_type=sa.UUID(), nullable=False
32
+ )
33
+ batch_op.create_unique_constraint(
34
+ "production_schedule_version_task_link_uc",
35
+ ["production_schedule_version_id", "task_id"],
36
+ )
37
+
38
+ # ### end Alembic commands ###
39
+
40
+
41
+ def downgrade():
42
+ # ### commands auto generated by Alembic - please adjust! ###
43
+ with op.batch_alter_table(
44
+ "production_schedule_version_task_link", schema=None
45
+ ) as batch_op:
46
+ batch_op.drop_constraint(
47
+ "production_schedule_version_task_link_uc", type_="unique"
48
+ )
49
+ batch_op.alter_column(
50
+ "task_id", existing_type=sa.UUID(), nullable=False
51
+ )
52
+ batch_op.alter_column(
53
+ "production_schedule_version_id",
54
+ existing_type=sa.UUID(),
55
+ nullable=False,
56
+ )
57
+
58
+ # ### end Alembic commands ###
@@ -0,0 +1,40 @@
1
+ """Add productionversionschedule uc
2
+
3
+ Revision ID: 26f96f65cfa3
4
+ Revises: 3d8e68dffeee
5
+ Create Date: 2025-07-18 11:49:59.302576
6
+
7
+ """
8
+
9
+ from alembic import op
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = "26f96f65cfa3"
14
+ down_revision = "3d8e68dffeee"
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade():
20
+ # ### commands auto generated by Alembic - please adjust! ###
21
+ with op.batch_alter_table(
22
+ "production_schedule_version", schema=None
23
+ ) as batch_op:
24
+ batch_op.create_unique_constraint(
25
+ "production_schedule_version_uc", ["name", "project_id"]
26
+ )
27
+
28
+ # ### end Alembic commands ###
29
+
30
+
31
+ def downgrade():
32
+ # ### commands auto generated by Alembic - please adjust! ###
33
+ with op.batch_alter_table(
34
+ "production_schedule_version", schema=None
35
+ ) as batch_op:
36
+ batch_op.drop_constraint(
37
+ "production_schedule_version_uc", type_="unique"
38
+ )
39
+
40
+ # ### end Alembic commands ###
@@ -0,0 +1,56 @@
1
+ """Fix TaskPersonLink
2
+
3
+ Revision ID: 3d8e68dffeee
4
+ Revises: d97f2730bf7b
5
+ Create Date: 2025-07-18 11:39:02.795034
6
+
7
+ """
8
+
9
+ from alembic import op
10
+
11
+ # revision identifiers, used by Alembic.
12
+ revision = "3d8e68dffeee"
13
+ down_revision = "d97f2730bf7b"
14
+ branch_labels = None
15
+ depends_on = None
16
+
17
+
18
+ def upgrade():
19
+ # ### commands auto generated by Alembic - please adjust! ###
20
+ with op.batch_alter_table("task_person_link", schema=None) as batch_op:
21
+ batch_op.alter_column("task", new_column_name="task_id")
22
+ batch_op.alter_column("person", new_column_name="person_id")
23
+ batch_op.drop_constraint(
24
+ batch_op.f("assignations_person_fkey"), type_="foreignkey"
25
+ )
26
+ batch_op.drop_constraint(
27
+ batch_op.f("assignations_task_fkey"), type_="foreignkey"
28
+ )
29
+ batch_op.create_foreign_key(None, "person", ["person_id"], ["id"])
30
+ batch_op.create_foreign_key(None, "task", ["task_id"], ["id"])
31
+
32
+ # ### end Alembic commands ###
33
+
34
+
35
+ def downgrade():
36
+ # ### commands auto generated by Alembic - please adjust! ###
37
+ with op.batch_alter_table("task_person_link", schema=None) as batch_op:
38
+ batch_op.alter_column("task_id", new_column_name="task")
39
+ batch_op.alter_column("person_id", new_column_name="person")
40
+ batch_op.drop_constraint(
41
+ "task_person_link_person_id_fkey", type_="foreignkey"
42
+ )
43
+ batch_op.drop_constraint(
44
+ "task_person_link_task_id_fkey", type_="foreignkey"
45
+ )
46
+ batch_op.create_foreign_key(
47
+ batch_op.f("assignations_task_fkey"), "task", ["task"], ["id"]
48
+ )
49
+ batch_op.create_foreign_key(
50
+ batch_op.f("assignations_person_fkey"),
51
+ "person",
52
+ ["person"],
53
+ ["id"],
54
+ )
55
+
56
+ # ### end Alembic commands ###
@@ -0,0 +1,188 @@
1
+ """ProductionScheduleVersion add on delete cascade to fkey
2
+
3
+ Revision ID: 4368137b44e1
4
+ Revises: 0bd1e89f2a6f
5
+ Create Date: 2025-07-23 00:41:37.354903
6
+
7
+ """
8
+
9
+ from alembic import op
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = "4368137b44e1"
14
+ down_revision = "0bd1e89f2a6f"
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade():
20
+ # ### commands auto generated by Alembic - please adjust! ###
21
+ with op.batch_alter_table(
22
+ "production_schedule_version", schema=None
23
+ ) as batch_op:
24
+ batch_op.drop_constraint(
25
+ batch_op.f(
26
+ "production_schedule_version_production_schedule_from_fkey"
27
+ ),
28
+ type_="foreignkey",
29
+ )
30
+ batch_op.drop_constraint(
31
+ batch_op.f("production_schedule_version_project_id_fkey"),
32
+ type_="foreignkey",
33
+ )
34
+ batch_op.create_foreign_key(
35
+ None, "project", ["project_id"], ["id"], ondelete="CASCADE"
36
+ )
37
+ batch_op.create_foreign_key(
38
+ None,
39
+ "production_schedule_version",
40
+ ["production_schedule_from"],
41
+ ["id"],
42
+ ondelete="CASCADE",
43
+ )
44
+
45
+ with op.batch_alter_table(
46
+ "production_schedule_version_task_link", schema=None
47
+ ) as batch_op:
48
+ batch_op.drop_constraint(
49
+ batch_op.f(
50
+ "production_schedule_version_t_production_schedule_version__fkey"
51
+ ),
52
+ type_="foreignkey",
53
+ )
54
+ batch_op.drop_constraint(
55
+ batch_op.f("production_schedule_version_task_link_task_id_fkey"),
56
+ type_="foreignkey",
57
+ )
58
+ batch_op.create_foreign_key(
59
+ None,
60
+ "production_schedule_version",
61
+ ["production_schedule_version_id"],
62
+ ["id"],
63
+ ondelete="CASCADE",
64
+ )
65
+ batch_op.create_foreign_key(
66
+ None, "task", ["task_id"], ["id"], ondelete="CASCADE"
67
+ )
68
+
69
+ with op.batch_alter_table(
70
+ "production_schedule_version_task_link_person_link", schema=None
71
+ ) as batch_op:
72
+ batch_op.drop_constraint(
73
+ batch_op.f(
74
+ "production_schedule_version_task_link_person_lin_person_id_fkey"
75
+ ),
76
+ type_="foreignkey",
77
+ )
78
+ batch_op.drop_constraint(
79
+ batch_op.f(
80
+ "production_schedule_version__production_schedule_version__fkey1"
81
+ ),
82
+ type_="foreignkey",
83
+ )
84
+ batch_op.create_foreign_key(
85
+ None,
86
+ "production_schedule_version_task_link",
87
+ ["production_schedule_version_task_link_id"],
88
+ ["id"],
89
+ ondelete="CASCADE",
90
+ )
91
+ batch_op.create_foreign_key(
92
+ None, "person", ["person_id"], ["id"], ondelete="CASCADE"
93
+ )
94
+
95
+ # ### end Alembic commands ###
96
+
97
+
98
+ def downgrade():
99
+ # ### commands auto generated by Alembic - please adjust! ###
100
+ with op.batch_alter_table(
101
+ "production_schedule_version_task_link_person_link", schema=None
102
+ ) as batch_op:
103
+ batch_op.drop_constraint(
104
+ batch_op.f(
105
+ "production_schedule_version_task_link_person_lin_person_id_fkey"
106
+ ),
107
+ type_="foreignkey",
108
+ )
109
+ batch_op.drop_constraint(
110
+ batch_op.f(
111
+ "production_schedule_version__production_schedule_version__fkey1"
112
+ ),
113
+ type_="foreignkey",
114
+ )
115
+ batch_op.create_foreign_key(
116
+ batch_op.f(
117
+ "production_schedule_version__production_schedule_version__fkey1"
118
+ ),
119
+ "production_schedule_version_task_link",
120
+ ["production_schedule_version_task_link_id"],
121
+ ["id"],
122
+ )
123
+ batch_op.create_foreign_key(
124
+ batch_op.f(
125
+ "production_schedule_version_task_link_person_lin_person_id_fkey"
126
+ ),
127
+ "person",
128
+ ["person_id"],
129
+ ["id"],
130
+ )
131
+
132
+ with op.batch_alter_table(
133
+ "production_schedule_version_task_link", schema=None
134
+ ) as batch_op:
135
+ batch_op.drop_constraint(
136
+ batch_op.f(
137
+ "production_schedule_version_t_production_schedule_version__fkey"
138
+ ),
139
+ type_="foreignkey",
140
+ )
141
+ batch_op.drop_constraint(
142
+ batch_op.f("production_schedule_version_task_link_task_id_fkey"),
143
+ type_="foreignkey",
144
+ )
145
+ batch_op.create_foreign_key(
146
+ batch_op.f("production_schedule_version_task_link_task_id_fkey"),
147
+ "task",
148
+ ["task_id"],
149
+ ["id"],
150
+ )
151
+ batch_op.create_foreign_key(
152
+ batch_op.f(
153
+ "production_schedule_version_t_production_schedule_version__fkey"
154
+ ),
155
+ "production_schedule_version",
156
+ ["production_schedule_version_id"],
157
+ ["id"],
158
+ )
159
+
160
+ with op.batch_alter_table(
161
+ "production_schedule_version", schema=None
162
+ ) as batch_op:
163
+ batch_op.drop_constraint(
164
+ batch_op.f(
165
+ "production_schedule_version_production_schedule_from_fkey"
166
+ ),
167
+ type_="foreignkey",
168
+ )
169
+ batch_op.drop_constraint(
170
+ batch_op.f("production_schedule_version_project_id_fkey"),
171
+ type_="foreignkey",
172
+ )
173
+ batch_op.create_foreign_key(
174
+ batch_op.f("production_schedule_version_project_id_fkey"),
175
+ "project",
176
+ ["project_id"],
177
+ ["id"],
178
+ )
179
+ batch_op.create_foreign_key(
180
+ batch_op.f(
181
+ "production_schedule_version_production_schedule_from_fkey"
182
+ ),
183
+ "production_schedule_version",
184
+ ["production_schedule_from"],
185
+ ["id"],
186
+ )
187
+
188
+ # ### end Alembic commands ###
@@ -0,0 +1,49 @@
1
+ """add fields to the software table
2
+
3
+ Revision ID: 4bd9bfb73f11
4
+ Revises: 4d585b6956f2
5
+ Create Date: 2025-07-14 12:07:08.700862
6
+
7
+ """
8
+
9
+ from alembic import op
10
+ import sqlalchemy as sa
11
+
12
+
13
+ # revision identifiers, used by Alembic.
14
+ revision = "4bd9bfb73f11"
15
+ down_revision = "4d585b6956f2"
16
+ branch_labels = None
17
+ depends_on = None
18
+
19
+
20
+ def upgrade():
21
+ # ### commands auto generated by Alembic - please adjust! ###
22
+ with op.batch_alter_table("salary_scale", schema=None) as batch_op:
23
+ batch_op.alter_column(
24
+ "salary", existing_type=sa.INTEGER(), nullable=False
25
+ )
26
+
27
+ with op.batch_alter_table("software", schema=None) as batch_op:
28
+ batch_op.add_column(
29
+ sa.Column("monthly_cost", sa.Integer(), nullable=True)
30
+ )
31
+ batch_op.add_column(
32
+ sa.Column("inventory_amount", sa.Integer(), nullable=True)
33
+ )
34
+
35
+ # ### end Alembic commands ###
36
+
37
+
38
+ def downgrade():
39
+ # ### commands auto generated by Alembic - please adjust! ###
40
+ with op.batch_alter_table("software", schema=None) as batch_op:
41
+ batch_op.drop_column("inventory_amount")
42
+ batch_op.drop_column("monthly_cost")
43
+
44
+ with op.batch_alter_table("salary_scale", schema=None) as batch_op:
45
+ batch_op.alter_column(
46
+ "salary", existing_type=sa.INTEGER(), nullable=True
47
+ )
48
+
49
+ # ### end Alembic commands ###
@@ -0,0 +1,128 @@
1
+ """Add new table ProductionScheduleVersion
2
+
3
+ Revision ID: 5f715f2b6348
4
+ Revises: dde6be40f54f
5
+ Create Date: 2025-07-11 03:57:29.859765
6
+
7
+ """
8
+
9
+ from alembic import op
10
+ import sqlalchemy as sa
11
+ import sqlalchemy_utils
12
+ import sqlalchemy_utils
13
+ import uuid
14
+
15
+ # revision identifiers, used by Alembic.
16
+ revision = "5f715f2b6348"
17
+ down_revision = "dde6be40f54f"
18
+ branch_labels = None
19
+ depends_on = None
20
+
21
+
22
+ def upgrade():
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table(
25
+ "production_schedule_version",
26
+ sa.Column("name", sa.String(length=80), nullable=False),
27
+ sa.Column(
28
+ "project_id",
29
+ sqlalchemy_utils.types.uuid.UUIDType(binary=False),
30
+ default=uuid.uuid4,
31
+ nullable=False,
32
+ ),
33
+ sa.Column(
34
+ "production_schedule_from",
35
+ sqlalchemy_utils.types.uuid.UUIDType(binary=False),
36
+ default=uuid.uuid4,
37
+ nullable=True,
38
+ ),
39
+ sa.Column("locked", sa.Boolean(), nullable=True),
40
+ sa.Column("canceled", sa.Boolean(), nullable=True),
41
+ sa.Column(
42
+ "id",
43
+ sqlalchemy_utils.types.uuid.UUIDType(binary=False),
44
+ default=uuid.uuid4,
45
+ nullable=False,
46
+ ),
47
+ sa.Column("created_at", sa.DateTime(), nullable=True),
48
+ sa.Column("updated_at", sa.DateTime(), nullable=True),
49
+ sa.ForeignKeyConstraint(
50
+ ["production_schedule_from"],
51
+ ["production_schedule_version.id"],
52
+ ),
53
+ sa.ForeignKeyConstraint(
54
+ ["project_id"],
55
+ ["project.id"],
56
+ ),
57
+ sa.PrimaryKeyConstraint("id"),
58
+ )
59
+ with op.batch_alter_table(
60
+ "production_schedule_version", schema=None
61
+ ) as batch_op:
62
+ batch_op.create_index(
63
+ batch_op.f(
64
+ "ix_production_schedule_version_production_schedule_from"
65
+ ),
66
+ ["production_schedule_from"],
67
+ unique=False,
68
+ )
69
+ batch_op.create_index(
70
+ batch_op.f("ix_production_schedule_version_project_id"),
71
+ ["project_id"],
72
+ unique=False,
73
+ )
74
+
75
+ op.create_table(
76
+ "production_schedule_version_task_link",
77
+ sa.Column(
78
+ "production_schedule_version_id",
79
+ sqlalchemy_utils.types.uuid.UUIDType(binary=False),
80
+ default=uuid.uuid4,
81
+ nullable=False,
82
+ ),
83
+ sa.Column(
84
+ "task_id",
85
+ sqlalchemy_utils.types.uuid.UUIDType(binary=False),
86
+ default=uuid.uuid4,
87
+ nullable=False,
88
+ ),
89
+ sa.Column("start_date", sa.DateTime(), nullable=True),
90
+ sa.Column("due_date", sa.DateTime(), nullable=True),
91
+ sa.Column(
92
+ "id",
93
+ sqlalchemy_utils.types.uuid.UUIDType(binary=False),
94
+ default=uuid.uuid4,
95
+ nullable=False,
96
+ ),
97
+ sa.Column("created_at", sa.DateTime(), nullable=True),
98
+ sa.Column("updated_at", sa.DateTime(), nullable=True),
99
+ sa.ForeignKeyConstraint(
100
+ ["production_schedule_version_id"],
101
+ ["production_schedule_version.id"],
102
+ ),
103
+ sa.ForeignKeyConstraint(
104
+ ["task_id"],
105
+ ["task.id"],
106
+ ),
107
+ sa.PrimaryKeyConstraint("id"),
108
+ )
109
+ # ### end Alembic commands ###
110
+
111
+
112
+ def downgrade():
113
+ # ### commands auto generated by Alembic - please adjust! ###
114
+ op.drop_table("production_schedule_version_task_link")
115
+ with op.batch_alter_table(
116
+ "production_schedule_version", schema=None
117
+ ) as batch_op:
118
+ batch_op.drop_index(
119
+ batch_op.f("ix_production_schedule_version_project_id")
120
+ )
121
+ batch_op.drop_index(
122
+ batch_op.f(
123
+ "ix_production_schedule_version_production_schedule_from"
124
+ )
125
+ )
126
+
127
+ op.drop_table("production_schedule_version")
128
+ # ### end Alembic commands ###
@@ -26,8 +26,6 @@ def upgrade():
26
26
 
27
27
  def downgrade():
28
28
  # ### commands auto generated by Alembic - please adjust! ###
29
- with op.batch_alter_table("task", schema=None) as batch_op:
30
- batch_op.alter_column(
31
- "difficulty", existing_type=sa.INTEGER(), nullable=True
32
- )
29
+ with op.batch_alter_table("budget", schema=None) as batch_op:
30
+ batch_op.drop_column("currency")
33
31
  # ### end Alembic commands ###