healthdatalayer 1.6.6__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 (105) hide show
  1. healthdatalayer/__init__.py +0 -0
  2. healthdatalayer/config/__init__.py +0 -0
  3. healthdatalayer/config/config.py +24 -0
  4. healthdatalayer/config/db.py +12 -0
  5. healthdatalayer/config/vault.py +20 -0
  6. healthdatalayer/dtos/__init__.py +2 -0
  7. healthdatalayer/dtos/collaborator/__init__.py +0 -0
  8. healthdatalayer/dtos/collaborator/schedule_collaborator.py +13 -0
  9. healthdatalayer/dtos/medical_visit/__init__.py +0 -0
  10. healthdatalayer/dtos/medical_visit/medical_certificate.py +62 -0
  11. healthdatalayer/models/__init__.py +75 -0
  12. healthdatalayer/models/bridge_area_floor_branch/__init__.py +0 -0
  13. healthdatalayer/models/bridge_area_floor_branch/area.py +8 -0
  14. healthdatalayer/models/bridge_area_floor_branch/branch.py +16 -0
  15. healthdatalayer/models/bridge_area_floor_branch/bridge_area_floor_branch.py +27 -0
  16. healthdatalayer/models/bridge_area_floor_branch/floor.py +8 -0
  17. healthdatalayer/models/bridge_area_floor_branch/room.py +8 -0
  18. healthdatalayer/models/bridge_area_floor_branch/system.py +8 -0
  19. healthdatalayer/models/client/__init__.py +0 -0
  20. healthdatalayer/models/client/address.py +13 -0
  21. healthdatalayer/models/client/city.py +11 -0
  22. healthdatalayer/models/client/client.py +25 -0
  23. healthdatalayer/models/client/client_type.py +9 -0
  24. healthdatalayer/models/client/education.py +9 -0
  25. healthdatalayer/models/client/emergency_contact.py +17 -0
  26. healthdatalayer/models/client/gender.py +9 -0
  27. healthdatalayer/models/client/marriage_status.py +9 -0
  28. healthdatalayer/models/client/nationality.py +10 -0
  29. healthdatalayer/models/client/pathological_history.py +29 -0
  30. healthdatalayer/models/client/pet.py +16 -0
  31. healthdatalayer/models/client/profession.py +9 -0
  32. healthdatalayer/models/client/px.py +35 -0
  33. healthdatalayer/models/client/state.py +9 -0
  34. healthdatalayer/models/collaborator/__init__.py +0 -0
  35. healthdatalayer/models/collaborator/collaborator.py +33 -0
  36. healthdatalayer/models/collaborator/collaborator_speciality.py +8 -0
  37. healthdatalayer/models/collaborator/collaborator_type.py +9 -0
  38. healthdatalayer/models/collaborator/speciality.py +23 -0
  39. healthdatalayer/models/lab/__init__.py +0 -0
  40. healthdatalayer/models/lab/client_lab.py +13 -0
  41. healthdatalayer/models/lab/measure_lab.py +11 -0
  42. healthdatalayer/models/lab/medical_lab.py +17 -0
  43. healthdatalayer/models/medical_visit/__init__.py +0 -0
  44. healthdatalayer/models/medical_visit/medical_diagnosis.py +12 -0
  45. healthdatalayer/models/medical_visit/medical_diagnosis_visit.py +25 -0
  46. healthdatalayer/models/medical_visit/medical_drug.py +27 -0
  47. healthdatalayer/models/medical_visit/medical_drug_recipe.py +19 -0
  48. healthdatalayer/models/medical_visit/medical_recipe_visit.py +28 -0
  49. healthdatalayer/models/medical_visit/medical_visit.py +53 -0
  50. healthdatalayer/models/medical_visit/organ_system_review.py +28 -0
  51. healthdatalayer/models/medical_visit/physical_exam.py +45 -0
  52. healthdatalayer/models/medical_visit/status_visit_enum.py +8 -0
  53. healthdatalayer/models/medical_visit/visit_triage.py +28 -0
  54. healthdatalayer/models/user/__init__.py +0 -0
  55. healthdatalayer/models/user/permission.py +27 -0
  56. healthdatalayer/models/user/permission_user.py +8 -0
  57. healthdatalayer/models/user/role.py +27 -0
  58. healthdatalayer/models/user/role_permission.py +8 -0
  59. healthdatalayer/models/user/role_user.py +8 -0
  60. healthdatalayer/models/user/user.py +30 -0
  61. healthdatalayer/repositories/__init__.py +40 -0
  62. healthdatalayer/repositories/client_repositories/__init__.py +0 -0
  63. healthdatalayer/repositories/client_repositories/address_repository.py +94 -0
  64. healthdatalayer/repositories/client_repositories/client_type_repository.py +69 -0
  65. healthdatalayer/repositories/client_repositories/education_repository.py +70 -0
  66. healthdatalayer/repositories/client_repositories/emergency_contact_repository.py +78 -0
  67. healthdatalayer/repositories/client_repositories/gender_repository.py +70 -0
  68. healthdatalayer/repositories/client_repositories/marriage_status_repository.py +70 -0
  69. healthdatalayer/repositories/client_repositories/nationality_repository.py +69 -0
  70. healthdatalayer/repositories/client_repositories/pathological_history_repository.py +73 -0
  71. healthdatalayer/repositories/client_repositories/pet_repository.py +126 -0
  72. healthdatalayer/repositories/client_repositories/profession_repository.py +70 -0
  73. healthdatalayer/repositories/client_repositories/px_repository.py +239 -0
  74. healthdatalayer/repositories/collaborator_repositories/__init__.py +0 -0
  75. healthdatalayer/repositories/collaborator_repositories/collaborator_repository.py +197 -0
  76. healthdatalayer/repositories/collaborator_repositories/collaborator_type_repository.py +69 -0
  77. healthdatalayer/repositories/collaborator_repositories/speciality_repository.py +75 -0
  78. healthdatalayer/repositories/infraestructure_repositories/__init__.py +0 -0
  79. healthdatalayer/repositories/infraestructure_repositories/area_repository.py +69 -0
  80. healthdatalayer/repositories/infraestructure_repositories/branch_repository.py +69 -0
  81. healthdatalayer/repositories/infraestructure_repositories/bridge_repository.py +82 -0
  82. healthdatalayer/repositories/infraestructure_repositories/floor_repository.py +69 -0
  83. healthdatalayer/repositories/infraestructure_repositories/room_repository.py +69 -0
  84. healthdatalayer/repositories/infraestructure_repositories/system_repository.py +69 -0
  85. healthdatalayer/repositories/lab_repositories/__init__.py +0 -0
  86. healthdatalayer/repositories/lab_repositories/measure_lab_repository.py +80 -0
  87. healthdatalayer/repositories/lab_repositories/medical_lab_repository.py +254 -0
  88. healthdatalayer/repositories/medical_visit_repositories/__init__.py +0 -0
  89. healthdatalayer/repositories/medical_visit_repositories/medical_diagnosis_repository.py +98 -0
  90. healthdatalayer/repositories/medical_visit_repositories/medical_diagnosis_visit_repository.py +109 -0
  91. healthdatalayer/repositories/medical_visit_repositories/medical_drug_recipe_repository.py +71 -0
  92. healthdatalayer/repositories/medical_visit_repositories/medical_drug_repository.py +78 -0
  93. healthdatalayer/repositories/medical_visit_repositories/medical_recipe_visit_repository.py +93 -0
  94. healthdatalayer/repositories/medical_visit_repositories/medical_visit_repository.py +509 -0
  95. healthdatalayer/repositories/medical_visit_repositories/organ_system_review_repository.py +89 -0
  96. healthdatalayer/repositories/medical_visit_repositories/physical_exam_repository.py +89 -0
  97. healthdatalayer/repositories/medical_visit_repositories/visit_triage_repository.py +95 -0
  98. healthdatalayer/repositories/user_repositories/__init__.py +0 -0
  99. healthdatalayer/repositories/user_repositories/permission_repository.py +238 -0
  100. healthdatalayer/repositories/user_repositories/role_repository.py +174 -0
  101. healthdatalayer/repositories/user_repositories/user_repository.py +251 -0
  102. healthdatalayer-1.6.6.dist-info/METADATA +30 -0
  103. healthdatalayer-1.6.6.dist-info/RECORD +105 -0
  104. healthdatalayer-1.6.6.dist-info/WHEEL +5 -0
  105. healthdatalayer-1.6.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,239 @@
1
+ from typing import Optional, List
2
+ from uuid import UUID
3
+ from sqlmodel import select
4
+
5
+ from healthdatalayer.models import Px
6
+ from healthdatalayer.config.db import engines, get_session
7
+
8
+ class PxRepository:
9
+ def __init__(self, tenant: str):
10
+ self.tenant = tenant
11
+ if tenant not in engines:
12
+ raise ValueError(f"Tenant {tenant} is not configured")
13
+
14
+ def create_command(self, px: Px) -> Px:
15
+ with get_session(self.tenant) as session:
16
+ session.add(px)
17
+ session.commit()
18
+ session.refresh(px)
19
+ return px
20
+
21
+ def get_by_id_command(self, px_id: UUID, load_relations: bool = False) -> Optional[Px]:
22
+ with get_session(self.tenant) as session:
23
+ px = session.get(Px, px_id)
24
+
25
+ if px and load_relations:
26
+ if px.gender_id:
27
+ from healthdatalayer.models.client.gender import Gender
28
+ gender_obj = session.get(Gender, px.gender_id)
29
+ object.__setattr__(px, 'gender', gender_obj)
30
+
31
+ if px.address_id:
32
+ from healthdatalayer.models.client.address import Address
33
+ address_obj = session.get(Address, px.address_id)
34
+ object.__setattr__(px, 'address', address_obj)
35
+
36
+ if px.marriage_status_id:
37
+ from healthdatalayer.models.client.marriage_status import MarriageStatus
38
+ marriage_status_obj = session.get(MarriageStatus, px.marriage_status_id)
39
+ object.__setattr__(px, 'marriage_status', marriage_status_obj)
40
+
41
+ if px.profession_id:
42
+ from healthdatalayer.models.client.profession import Profession
43
+ profession_obj = session.get(Profession, px.profession_id)
44
+ object.__setattr__(px, 'profession', profession_obj)
45
+
46
+ if px.education_id:
47
+ from healthdatalayer.models.client.education import Education
48
+ education_obj = session.get(Education, px.education_id)
49
+ object.__setattr__(px, 'education', education_obj)
50
+
51
+ if px.user_id:
52
+ from healthdatalayer.models.user.user import User
53
+ user_obj = session.get(User, px.user_id)
54
+ object.__setattr__(px, 'user', user_obj)
55
+
56
+ if px.nationality_id:
57
+ from healthdatalayer.models.client.nationality import Nationality
58
+ user_obj = session.get(Nationality, px.nationality_id)
59
+ object.__setattr__(px, 'nationality', user_obj)
60
+
61
+ from healthdatalayer.models.client.pathological_history import PathologicalHistory
62
+ statement = select(PathologicalHistory).where(PathologicalHistory.client_id == px_id)
63
+ pathological_his = session.exec(statement).all()
64
+ if pathological_his:
65
+ object.__setattr__(px, 'pathological_histories',pathological_his)
66
+
67
+ return px
68
+
69
+ def get_by_identification_command(self, identification: str, load_relations: bool = False) -> Optional[Px]:
70
+ with get_session(self.tenant) as session:
71
+ statement = select(Px).where(Px.identification == identification)
72
+ px = session.exec(statement).first()
73
+
74
+ if px and load_relations:
75
+ if px.gender_id:
76
+ from healthdatalayer.models.client.gender import Gender
77
+ gender_obj = session.get(Gender, px.gender_id)
78
+ object.__setattr__(px, 'gender', gender_obj)
79
+
80
+ if px.address_id:
81
+ from healthdatalayer.models.client.address import Address
82
+ address_obj = session.get(Address, px.address_id)
83
+ object.__setattr__(px, 'address', address_obj)
84
+
85
+ if px.marriage_status_id:
86
+ from healthdatalayer.models.client.marriage_status import MarriageStatus
87
+ marriage_status_obj = session.get(MarriageStatus, px.marriage_status_id)
88
+ object.__setattr__(px, 'marriage_status', marriage_status_obj)
89
+
90
+ if px.profession_id:
91
+ from healthdatalayer.models.client.profession import Profession
92
+ profession_obj = session.get(Profession, px.profession_id)
93
+ object.__setattr__(px, 'profession', profession_obj)
94
+
95
+ if px.education_id:
96
+ from healthdatalayer.models.client.education import Education
97
+ education_obj = session.get(Education, px.education_id)
98
+ object.__setattr__(px, 'education', education_obj)
99
+
100
+ if px.user_id:
101
+ from healthdatalayer.models.user.user import User
102
+ user_obj = session.get(User, px.user_id)
103
+ object.__setattr__(px, 'user', user_obj)
104
+
105
+ if px.nationality_id:
106
+ from healthdatalayer.models.client.nationality import Nationality
107
+ user_obj = session.get(Nationality, px.nationality_id)
108
+ object.__setattr__(px, 'nationality', user_obj)
109
+
110
+
111
+ return px
112
+
113
+ def search_by_name_command(self, name: str, load_relations: bool = False) -> List[Px]:
114
+ with get_session(self.tenant) as session:
115
+ statement = select(Px).where(
116
+ (Px.first_name.ilike(f"%{name}%")) |
117
+ (Px.last_name.ilike(f"%{name}%")) |
118
+ (Px.identification.ilike(f"%{name}%"))
119
+ )
120
+
121
+ results = session.exec(statement).all()
122
+
123
+ if load_relations:
124
+ for px in results:
125
+ if px.gender_id:
126
+ from healthdatalayer.models.client.gender import Gender
127
+ gender_obj = session.get(Gender, px.gender_id)
128
+ object.__setattr__(px, 'gender', gender_obj)
129
+
130
+ if px.address_id:
131
+ from healthdatalayer.models.client.address import Address
132
+ address_obj = session.get(Address, px.address_id)
133
+ object.__setattr__(px, 'address', address_obj)
134
+
135
+ if px.marriage_status_id:
136
+ from healthdatalayer.models.client.marriage_status import MarriageStatus
137
+ marriage_status_obj = session.get(MarriageStatus, px.marriage_status_id)
138
+ object.__setattr__(px, 'marriage_status', marriage_status_obj)
139
+
140
+ if px.profession_id:
141
+ from healthdatalayer.models.client.profession import Profession
142
+ profession_obj = session.get(Profession, px.profession_id)
143
+ object.__setattr__(px, 'profession', profession_obj)
144
+
145
+ if px.education_id:
146
+ from healthdatalayer.models.client.education import Education
147
+ education_obj = session.get(Education, px.education_id)
148
+ object.__setattr__(px, 'education', education_obj)
149
+
150
+ if px.user_id:
151
+ from healthdatalayer.models.user.user import User
152
+ user_obj = session.get(User, px.user_id)
153
+ object.__setattr__(px, 'user', user_obj)
154
+ if px.nationality_id:
155
+ from healthdatalayer.models.client.nationality import Nationality
156
+ user_obj = session.get(Nationality, px.nationality_id)
157
+ object.__setattr__(px, 'nationality', user_obj)
158
+
159
+
160
+ return results
161
+
162
+ def list_all_command(self, active_only: bool = True, load_relations: bool = False) -> List[Px]:
163
+ with get_session(self.tenant) as session:
164
+ statement = select(Px)
165
+
166
+ if active_only:
167
+ statement = statement.where(Px.is_active == True)
168
+
169
+ results = session.exec(statement).all()
170
+
171
+ if load_relations:
172
+ for px in results:
173
+ if px.gender_id:
174
+ from healthdatalayer.models.client.gender import Gender
175
+ gender_obj = session.get(Gender, px.gender_id)
176
+ object.__setattr__(px, 'gender', gender_obj)
177
+
178
+ if px.address_id:
179
+ from healthdatalayer.models.client.address import Address
180
+ address_obj = session.get(Address, px.address_id)
181
+ object.__setattr__(px, 'address', address_obj)
182
+
183
+ if px.marriage_status_id:
184
+ from healthdatalayer.models.client.marriage_status import MarriageStatus
185
+ marriage_status_obj = session.get(MarriageStatus, px.marriage_status_id)
186
+ object.__setattr__(px, 'marriage_status', marriage_status_obj)
187
+
188
+ if px.profession_id:
189
+ from healthdatalayer.models.client.profession import Profession
190
+ profession_obj = session.get(Profession, px.profession_id)
191
+ object.__setattr__(px, 'profession', profession_obj)
192
+
193
+ if px.education_id:
194
+ from healthdatalayer.models.client.education import Education
195
+ education_obj = session.get(Education, px.education_id)
196
+ object.__setattr__(px, 'education', education_obj)
197
+
198
+ if px.user_id:
199
+ from healthdatalayer.models.user.user import User
200
+ user_obj = session.get(User, px.user_id)
201
+ object.__setattr__(px, 'user', user_obj)
202
+
203
+ if px.nationality_id:
204
+ from healthdatalayer.models.client.nationality import Nationality
205
+ user_obj = session.get(Nationality, px.nationality_id)
206
+ object.__setattr__(px, 'nationality', user_obj)
207
+
208
+
209
+ return results
210
+
211
+ def update_command(self, px: Px) -> Px:
212
+ with get_session(self.tenant) as session:
213
+ db_px = session.merge(px)
214
+ session.commit()
215
+ session.refresh(db_px)
216
+ return db_px
217
+
218
+ def delete_command(self, px_id: UUID, soft_delete: bool = True) -> bool:
219
+ with get_session(self.tenant) as session:
220
+ db_px = session.get(Px, px_id)
221
+ if not db_px:
222
+ return False
223
+
224
+ if soft_delete:
225
+ db_px.is_active = False
226
+ session.add(db_px)
227
+ else:
228
+ session.delete(db_px)
229
+
230
+ session.commit()
231
+ return True
232
+
233
+ def count_command(self, active_only: bool = True) -> int:
234
+ with get_session(self.tenant) as session:
235
+ statement = select(Px)
236
+ if active_only:
237
+ statement = statement.where(Px.is_active == True)
238
+ results = session.exec(statement)
239
+ return len(results.all())
@@ -0,0 +1,197 @@
1
+ from datetime import date
2
+ from typing import Optional, List
3
+ from uuid import UUID
4
+ from sqlmodel import select, or_, join, text
5
+ from sqlalchemy.orm import selectinload,joinedload
6
+ from healthdatalayer.models import Collaborator
7
+ from healthdatalayer.models import Speciality, CollaboratorSpeciality
8
+ from healthdatalayer.dtos import ScheduleCollaboratorDTO
9
+ from healthdatalayer.config.db import engines, get_session
10
+
11
+ class CollaboratorRepository:
12
+ def __init__(self, tenant: str):
13
+ self.tenant = tenant
14
+ if tenant not in engines:
15
+ raise ValueError(f"Tenant {tenant} is not configured")
16
+
17
+ def create_command(self, collaborator: Collaborator) -> Collaborator:
18
+ with get_session(self.tenant) as session:
19
+ session.add(collaborator)
20
+ session.commit()
21
+ session.refresh(collaborator)
22
+ return collaborator
23
+
24
+ def get_by_id_command(self, collaborator_id: UUID, load_relations: bool = False) -> Optional[Collaborator]:
25
+ with get_session(self.tenant) as session:
26
+ if load_relations:
27
+ statement = select(Collaborator).where(Collaborator.collaborator_id == collaborator_id).options(
28
+ selectinload(Collaborator.collaborator_type),
29
+ joinedload(Collaborator.user),
30
+ selectinload(Collaborator.specialties)
31
+ )
32
+ collaborator = session.exec(statement).first()
33
+
34
+ return collaborator
35
+ else:
36
+ return session.get(Collaborator, collaborator_id)
37
+
38
+ def get_by_speciality_id_command(self, speciality_id: UUID, load_relations: bool = False) -> List[Collaborator]:
39
+ with get_session(self.tenant) as session:
40
+ statement = (
41
+ select(Collaborator)
42
+ .join(CollaboratorSpeciality)
43
+ .where(CollaboratorSpeciality.speciality_id == speciality_id, Collaborator.is_active == True)
44
+ )
45
+
46
+ if load_relations:
47
+ statement = statement.options(
48
+ selectinload(Collaborator.collaborator_type),
49
+ joinedload(Collaborator.user),
50
+ selectinload(Collaborator.specialties)
51
+ )
52
+
53
+ collaborators = session.exec(statement).all()
54
+
55
+ return collaborators
56
+
57
+ def get_by_ruc_name_code_command(self, content: str, active_only: bool = True, load_relations : bool = False)->List[Collaborator]:
58
+ with get_session(self.tenant) as session:
59
+
60
+ query = select(Collaborator).where(
61
+ or_(
62
+ Collaborator.name.ilike(f"%{content}%"),
63
+ Collaborator.ruc.ilike(f"%{content}%"),
64
+ Collaborator.code.ilike(f"%{content}%")
65
+ )
66
+ )
67
+
68
+ if load_relations:
69
+ query = select(Collaborator).options(
70
+ selectinload(Collaborator.collaborator_type),
71
+ joinedload(Collaborator.user),
72
+ selectinload(Collaborator.specialties)
73
+ ).where(
74
+ or_(
75
+ Collaborator.name.ilike(f"%{content}%"),
76
+ Collaborator.ruc.ilike(f"%{content}%"),
77
+ Collaborator.code.ilike(f"%{content}%")
78
+ )
79
+ )
80
+
81
+ if active_only:
82
+ query.where(Collaborator.is_active == True)
83
+
84
+ collaborators = session.exec(query).all()
85
+
86
+ return collaborators
87
+
88
+
89
+ def get_all_command(self, active_only: bool = True,load_related: bool = False) -> List[Collaborator]:
90
+ with get_session(self.tenant) as session:
91
+
92
+ statement = select(Collaborator)
93
+
94
+ if load_related:
95
+
96
+ statement = statement.options(
97
+ selectinload(Collaborator.collaborator_type),
98
+ joinedload(Collaborator.user),
99
+ selectinload(Collaborator.specialties)
100
+ )
101
+
102
+ if active_only:
103
+ statement = statement.where(Collaborator.is_active == True)
104
+
105
+ return session.exec(statement).all()
106
+
107
+ def update_command(self, collaborator: Collaborator) -> Collaborator:
108
+ with get_session(self.tenant) as session:
109
+ existing_collaborator = session.get(Collaborator, collaborator.collaborator_id)
110
+ if not existing_collaborator:
111
+ raise ValueError(f"collaborator with id {collaborator.collaborator_id} does not exist")
112
+
113
+ for key, value in collaborator.dict(exclude_unset=True).items():
114
+ setattr(existing_collaborator, key, value)
115
+
116
+ bd_collaborator = session.merge(existing_collaborator)
117
+ session.commit()
118
+ session.refresh(bd_collaborator)
119
+ return bd_collaborator
120
+
121
+ def delete_command(self, collaborator_id: UUID, soft_delete: bool = False)->None:
122
+ with get_session(self.tenant) as session:
123
+ existing_bridge = session.get(Collaborator, collaborator_id)
124
+ if not existing_bridge:
125
+ raise ValueError(f"Collaborator with id {collaborator_id} does not exist")
126
+
127
+ if soft_delete:
128
+ existing_bridge.is_active = False
129
+ session.add(existing_bridge)
130
+ else:
131
+ session.delete(existing_bridge)
132
+
133
+ session.commit()
134
+
135
+ def assign_speciality_command(self, collaborator_id: UUID, speciality_id: UUID) -> Optional[Collaborator]:
136
+ with get_session(self.tenant) as session:
137
+ collab_statement = select(Collaborator).options(selectinload(Collaborator.specialties)).where(Collaborator.collaborator_id == collaborator_id)
138
+ collab = session.exec(collab_statement).first()
139
+ if not collab:
140
+ return None
141
+
142
+ speciality = session.get(Speciality, speciality_id)
143
+ if not speciality:
144
+ return None
145
+
146
+ if speciality not in collab.specialties:
147
+ collab.specialties.append(speciality)
148
+ session.add(collab)
149
+ session.commit()
150
+ session.refresh(collab)
151
+
152
+ return collab
153
+
154
+ def get_availability_schedules_command(self, visit_date: date, collaborator_id: str) -> ScheduleCollaboratorDTO:
155
+
156
+ with get_session(self.tenant) as session:
157
+
158
+ query = text("""
159
+ WITH horarios_generados AS (
160
+ SELECT horario::TIME as hora
161
+ FROM generate_series(
162
+ CAST(:fecha AS DATE)+ TIME '08:00:00',
163
+ CAST(:fecha AS DATE) + TIME '17:00:00',
164
+ INTERVAL '30 minutes'
165
+ ) AS horario
166
+ ),
167
+ horarios_ocupados AS (
168
+ SELECT t.visit_date::TIME as hora
169
+ FROM medical_visit t
170
+ WHERE t.visit_date::DATE = :fecha
171
+ AND t.collaborator_id = :colab_id
172
+ AND t.status_visit in ('AGENDADO','REAGENDADO')
173
+ )
174
+ SELECT
175
+ hg.hora,
176
+ CASE WHEN ho.hora IS NOT NULL THEN true ELSE false END as ocupado
177
+ FROM horarios_generados hg
178
+ LEFT JOIN horarios_ocupados ho ON hg.hora = ho.hora
179
+ ORDER BY hg.hora
180
+ """)
181
+
182
+ result = session.exec(query, params={"fecha": visit_date, "colab_id": collaborator_id})
183
+
184
+ availables = []
185
+ busy = []
186
+
187
+ for row in result.fetchall():
188
+ hour, is_busy = row[0], row[1]
189
+ if is_busy:
190
+ busy.append(hour)
191
+ else:
192
+ availables.append(hour)
193
+
194
+ return ScheduleCollaboratorDTO(
195
+ available_schedules=availables,
196
+ busy_schedules=busy
197
+ )
@@ -0,0 +1,69 @@
1
+ from typing import Optional, List
2
+ from uuid import UUID
3
+ from sqlmodel import select
4
+
5
+ from healthdatalayer.models import CollaboratorType
6
+ from healthdatalayer.config.db import engines, get_session
7
+
8
+ class CollaboratorTypeRepository:
9
+ def __init__(self, tenant: str):
10
+ self.tenant = tenant
11
+ if tenant not in engines:
12
+ raise ValueError(f"Tenant {tenant} is not configured")
13
+
14
+ def create_command(self,collaborator_type : CollaboratorType)-> CollaboratorType:
15
+ with get_session(self.tenant) as session:
16
+ session.add(collaborator_type)
17
+ session.commit()
18
+ session.refresh(collaborator_type)
19
+ return collaborator_type
20
+
21
+ def get_by_id_command(self, collaborator_type_id: UUID) -> Optional[CollaboratorType]:
22
+ with get_session(self.tenant) as session:
23
+ return session.get(CollaboratorType, collaborator_type_id)
24
+
25
+ def get_by_name_command(self, name: str) -> Optional[CollaboratorType]:
26
+ with get_session(self.tenant) as session:
27
+ statement = select(CollaboratorType).where(CollaboratorType.name == name)
28
+ result = session.exec(statement).first()
29
+ return result
30
+
31
+ def list_all_command(self, active_only: bool = True) -> List[CollaboratorType]:
32
+ with get_session(self.tenant) as session:
33
+ statement = select(CollaboratorType)
34
+
35
+ if active_only:
36
+ statement = statement.where(CollaboratorType.is_active == True)
37
+
38
+ results = session.exec(statement)
39
+ return results.all()
40
+
41
+ def update_command(self, collaborator_type_id: UUID, **kwargs) -> Optional[CollaboratorType]:
42
+ with get_session(self.tenant) as session:
43
+ db_collaborator_type = session.get(CollaboratorType, collaborator_type_id)
44
+ if not db_collaborator_type:
45
+ return None
46
+
47
+ for key, value in kwargs.items():
48
+ if hasattr(db_collaborator_type, key):
49
+ setattr(db_collaborator_type, key, value)
50
+
51
+ session.add(db_collaborator_type)
52
+ session.commit()
53
+ session.refresh(db_collaborator_type)
54
+ return db_collaborator_type
55
+
56
+ def delete_command(self, collaborator_type_id: UUID, soft_delete: bool = True) -> bool:
57
+ with get_session(self.tenant) as session:
58
+ db_collaborator_type = session.get(CollaboratorType, collaborator_type_id)
59
+ if not db_collaborator_type:
60
+ return False
61
+
62
+ if soft_delete:
63
+ db_collaborator_type.is_active = False
64
+ session.add(db_collaborator_type)
65
+ else:
66
+ session.delete(db_collaborator_type)
67
+
68
+ session.commit()
69
+ return True
@@ -0,0 +1,75 @@
1
+ from typing import Optional, List
2
+ from uuid import UUID
3
+ from sqlmodel import select
4
+
5
+ from healthdatalayer.models import Speciality
6
+ from healthdatalayer.config.db import engines, get_session
7
+
8
+ class SpecialityRepository:
9
+ def __init__(self, tenant: str):
10
+ self.tenant = tenant
11
+ if tenant not in engines:
12
+ raise ValueError(f"Tenant {tenant} is not configured")
13
+
14
+ def create_command(self, speciality : Speciality) -> Speciality:
15
+ with get_session(self.tenant) as session:
16
+ session.add(speciality)
17
+ session.commit()
18
+ session.refresh(speciality)
19
+ return speciality
20
+
21
+ def get_by_id_command(self, speciality_id: UUID) -> Optional[Speciality]:
22
+ with get_session(self.tenant) as session:
23
+ return session.get(Speciality, speciality_id)
24
+
25
+ def get_by_name_command(self, name: str) -> Optional[Speciality]:
26
+ with get_session(self.tenant) as session:
27
+ statement = select(Speciality).where(Speciality.name == name)
28
+ result = session.exec(statement).first()
29
+ return result
30
+
31
+ def get_by_subspeciality_command(self, subspeciality: str) -> Optional[List[Speciality]]:
32
+ with get_session(self.tenant) as session:
33
+ statement = select(Speciality).where(Speciality.subspeciality == subspeciality)
34
+ result = session.exec(statement).first()
35
+ return result
36
+
37
+ def list_all_command(self, active_only: bool = True) -> List[Speciality]:
38
+ with get_session(self.tenant) as session:
39
+ statement = select(Speciality)
40
+
41
+ if active_only:
42
+ statement = statement.where(Speciality.is_active == True)
43
+
44
+ results = session.exec(statement)
45
+ return results.all()
46
+
47
+ def update_command(self, speciality_id: UUID, **kwargs) -> Optional[Speciality]:
48
+ with get_session(self.tenant) as session:
49
+ db_speciality = session.get(Speciality, speciality_id)
50
+ if not db_speciality:
51
+ return None
52
+
53
+ for key, value in kwargs.items():
54
+ if hasattr(db_speciality, key):
55
+ setattr(db_speciality, key, value)
56
+
57
+ session.add(db_speciality)
58
+ session.commit()
59
+ session.refresh(db_speciality)
60
+ return db_speciality
61
+
62
+ def delete_command(self, speciality_id: UUID, soft_delete: bool = True) -> bool:
63
+ with get_session(self.tenant) as session:
64
+ db_speciality = session.get(Speciality, speciality_id)
65
+ if not db_speciality:
66
+ return False
67
+
68
+ if soft_delete:
69
+ db_speciality.is_active = False
70
+ session.add(db_speciality)
71
+ else:
72
+ session.delete(db_speciality)
73
+
74
+ session.commit()
75
+ return True
@@ -0,0 +1,69 @@
1
+ from typing import Optional, List
2
+ from uuid import UUID
3
+ from sqlmodel import select
4
+
5
+ from healthdatalayer.models import Area
6
+ from healthdatalayer.config.db import engines, get_session
7
+
8
+ class AreaRepository:
9
+ def __init__(self, tenant: str):
10
+ self.tenant = tenant
11
+ if tenant not in engines:
12
+ raise ValueError(f"Tenant {tenant} is not configured")
13
+
14
+ def create_command(self, area: Area) -> Area:
15
+ with get_session(self.tenant) as session:
16
+ session.add(area)
17
+ session.commit()
18
+ session.refresh(area)
19
+ return area
20
+
21
+ def get_by_id_command(self, area_id: UUID) -> Optional[Area]:
22
+ with get_session(self.tenant) as session:
23
+ return session.get(Area, area_id)
24
+
25
+ def get_by_name_command(self, name: str) -> Optional[Area]:
26
+ with get_session(self.tenant) as session:
27
+ statement = select(Area).where(Area.name == name)
28
+ result = session.exec(statement).first()
29
+ return result
30
+
31
+ def list_all_command(self, active_only: bool = True) -> List[Area]:
32
+ with get_session(self.tenant) as session:
33
+ statement = select(Area)
34
+
35
+ if active_only:
36
+ statement = statement.where(Area.is_active == True)
37
+
38
+ results = session.exec(statement)
39
+ return results.all()
40
+
41
+ def update_command(self, area_id: UUID, **kwargs) -> Optional[Area]:
42
+ with get_session(self.tenant) as session:
43
+ db_area = session.get(Area, area_id)
44
+ if not db_area:
45
+ return None
46
+
47
+ for key, value in kwargs.items():
48
+ if hasattr(db_area, key):
49
+ setattr(db_area, key, value)
50
+
51
+ session.add(db_area)
52
+ session.commit()
53
+ session.refresh(db_area)
54
+ return db_area
55
+
56
+ def delete_command(self, area_id: UUID, soft_delete: bool = True) -> bool:
57
+ with get_session(self.tenant) as session:
58
+ db_area = session.get(Area, area_id)
59
+ if not db_area:
60
+ return False
61
+
62
+ if soft_delete:
63
+ db_area.is_active = False
64
+ session.add(db_area)
65
+ else:
66
+ session.delete(db_area)
67
+
68
+ session.commit()
69
+ return True