1 """GNUmed family history handling middleware"""
2
3 __license__ = "GPL"
4 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
5
6
7
8 import sys, logging
9
10
11
12 if __name__ == '__main__':
13 sys.path.insert(0, '../../')
14 from Gnumed.pycommon import gmPG2
15 from Gnumed.pycommon import gmBusinessDBObject
16 from Gnumed.pycommon import gmDateTime
17 from Gnumed.pycommon import gmTools
18
19 from Gnumed.business import gmCoding
20
21
22 _log = logging.getLogger('gm.fhx')
23
24
25
26
28
29 args = {'rel': relationship, 'gen': genetic}
30
31
32 cmd = u"""
33 SELECT *, _(description) as l10n_description
34 FROM clin.fhx_relation_type
35 WHERE
36 description = %(rel)s
37 OR
38 _(description) = %(rel)s
39 """
40 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
41 if len(rows) > 0:
42 return rows[0]
43
44
45 cmd = u"""
46 INSERT INTO clin.fhx_relation_type (
47 description,
48 is_genetic
49 ) VALUES (
50 i18n.i18n(gm.nullify_empty_string(%(rel)s)),
51 %(gen)s
52 )
53 RETURNING *
54 """
55 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
56 return rows[0]
57
58
59
60 _SQL_get_family_history = u"SELECT * from clin.v_family_history WHERE %s"
61
62 -class cFamilyHistory(gmBusinessDBObject.cBusinessDBObject):
63 """Represents a Family History item."""
64
65 _cmd_fetch_payload = _SQL_get_family_history % u"pk_family_history = %s"
66 _cmds_store_payload = [
67 u"""
68 UPDATE clin.family_history SET
69 narrative = gm.nullify_empty_string(%(condition)s),
70 age_noted = gm.nullify_empty_string(%(age_noted)s),
71 age_of_death = %(age_of_death)s,
72 contributed_to_death = %(contributed_to_death)s,
73 clin_when = %(when_known_to_patient)s,
74 name_relative = gm.nullify_empty_string(%(name_relative)s),
75 dob_relative = %(dob_relative)s,
76 comment = gm.nullify_empty_string(%(comment)s),
77 fk_episode = %(pk_episode)s,
78 fk_relation_type = %(pk_fhx_relation_type)s
79 WHERE
80 pk = %(pk_family_history)s
81 AND
82 xmin = %(xmin_family_history)s
83 RETURNING
84 pk as pk_family_history,
85 xmin as xmin_family_history
86 """
87 ]
88
89 _updatable_fields = [
90 u'condition',
91 u'age_noted',
92 u'age_of_death',
93 u'contributed_to_death',
94 u'when_known_to_patient',
95 u'name_relative',
96 u'dob_relative',
97 u'pk_encounter',
98 u'pk_episode',
99 u'pk_fhx_relation_type',
100 u'comment'
101 ]
102
103 - def add_code(self, pk_code=None):
104 """<pk_code> must be a value from ref.coding_system_root.pk_coding_system (clin.lnk_code2item_root.fk_generic_code)"""
105
106 if pk_code in self._payload[self._idx['pk_generic_codes']]:
107 return
108
109 cmd = u"""
110 INSERT INTO clin.lnk_code2fhx
111 (fk_item, fk_generic_code)
112 SELECT
113 %(item)s,
114 %(code)s
115 WHERE NOT EXISTS (
116 SELECT 1 FROM clin.lnk_code2fhx
117 WHERE
118 fk_item = %(item)s
119 AND
120 fk_generic_code = %(code)s
121 )"""
122 args = {
123 'item': self._payload[self._idx['pk_family_history']],
124 'code': pk_code
125 }
126 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
127 return
128
129 - def remove_code(self, pk_code=None):
130 """<pk_code> must be a value from ref.coding_system_root.pk_coding_system (clin.lnk_code2item_root.fk_generic_code)"""
131 cmd = u"DELETE FROM clin.lnk_code2fhx WHERE fk_item = %(item)s AND fk_generic_code = %(code)s"
132 args = {
133 'item': self._payload[self._idx['pk_family_history']],
134 'code': pk_code
135 }
136 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
137 return True
138
139 - def format(self, left_margin=0, include_episode=False, include_comment=False, include_codes=False):
140
141 line = u'%s%s' % (
142 (u' ' * left_margin),
143 self._payload[self._idx['l10n_relation']]
144 )
145 if self._payload[self._idx['age_of_death']] is not None:
146 line += u' (%s %s)' % (
147 gmTools.u_latin_cross,
148 gmDateTime.format_interval_medically(self._payload[self._idx['age_of_death']])
149 )
150 line += u': %s' % self._payload[self._idx['condition']]
151 if self._payload[self._idx['age_noted']] is not None:
152 line += gmTools.coalesce(self._payload[self._idx['age_noted']], u'', u' (@ %s)')
153 if self._payload[self._idx['contributed_to_death']]:
154 line += u' %s %s' % (
155 gmTools.u_right_arrow,
156 gmTools.u_skull_and_crossbones
157 )
158
159 if include_episode:
160 line += u'\n%s %s: %s' % (
161 (u' ' * left_margin),
162 _('Episode'),
163 self._payload[self._idx['episode']]
164 )
165
166 if include_comment:
167 if self._payload[self._idx['comment']] is not None:
168 line += u'\n%s %s' % (
169 (u' ' * left_margin),
170 self._payload[self._idx['comment']]
171 )
172
173 if include_codes:
174 codes = self.generic_codes
175 if len(codes) > 0:
176 line += u'\n'
177 for c in codes:
178 line += u'%s %s: %s (%s - %s)\n' % (
179 (u' ' * left_margin),
180 c['code'],
181 c['term'],
182 c['name_short'],
183 c['version']
184 )
185 del codes
186
187 return line
188
189
190
192 if len(self._payload[self._idx['pk_generic_codes']]) == 0:
193 return []
194
195 cmd = gmCoding._SQL_get_generic_linked_codes % u'pk_generic_code IN %(pks)s'
196 args = {'pks': tuple(self._payload[self._idx['pk_generic_codes']])}
197 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
198 return [ gmCoding.cGenericLinkedCode(row = {'data': r, 'idx': idx, 'pk_field': 'pk_lnk_code2item'}) for r in rows ]
199
200 - def _set_generic_codes(self, pk_codes):
201 queries = []
202
203 if len(self._payload[self._idx['pk_generic_codes']]) > 0:
204 queries.append ({
205 'cmd': u'DELETE FROM clin.lnk_code2fhx WHERE fk_item = %(fhx)s AND fk_generic_code IN %(codes)s',
206 'args': {
207 'fhx': self._payload[self._idx['pk_family_history']],
208 'codes': tuple(self._payload[self._idx['pk_generic_codes']])
209 }
210 })
211
212 for pk_code in pk_codes:
213 queries.append ({
214 'cmd': u'INSERT INTO clin.lnk_code2fhx (fk_item, fk_generic_code) VALUES (%(fhx)s, %(pk_code)s)',
215 'args': {
216 'fhx': self._payload[self._idx['pk_family_history']],
217 'pk_code': pk_code
218 }
219 })
220 if len(queries) == 0:
221 return
222
223 rows, idx = gmPG2.run_rw_queries(queries = queries)
224 return
225
226 generic_codes = property(_get_generic_codes, _set_generic_codes)
227
228 -def get_family_history(order_by=None, patient=None):
229
230 args = {}
231 where_parts = []
232
233 if patient is not None:
234 where_parts.append(u'pk_patient = %(pat)s')
235 args['pat'] = patient
236
237 if order_by is None:
238 if len(where_parts) == 0:
239 order_by = u'true'
240 else:
241 order_by = u''
242 else:
243 if len(where_parts) == 0:
244 order_by = u'true ORDER BY %s' % order_by
245 else:
246 order_by = u'ORDER BY %s' % order_by
247
248 cmd = _SQL_get_family_history % u' AND '.join(where_parts) + u' ' + order_by
249 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
250 return [ cFamilyHistory(row = {'data': r, 'idx': idx, 'pk_field': 'pk_family_history'}) for r in rows ]
251
252 -def create_family_history(encounter=None, episode=None, condition=None, relation=None):
253
254 args = {
255 u'enc': encounter,
256 u'epi': episode,
257 u'cond': condition,
258 u'rel': relation
259 }
260 cmd = u"""
261 INSERT INTO clin.family_history (
262 soap_cat,
263 fk_encounter,
264 fk_episode,
265 narrative,
266 fk_relation_type
267 ) VALUES (
268 's'::text,
269 %(enc)s,
270 %(epi)s,
271 gm.nullify_empty_string(%(cond)s),
272 %(rel)s
273 )
274 RETURNING pk
275 """
276 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
277
278 return cFamilyHistory(aPK_obj = rows[0]['pk'])
279
280 -def delete_family_history(pk_family_history=None):
281 args = {'pk': pk_family_history}
282 cmd = u"DELETE FROM clin.family_history WHERE pk = %(pk)s"
283 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
284 return True
285
286
287
288 if __name__ == "__main__":
289
290 if len(sys.argv) < 2:
291 sys.exit()
292
293 if sys.argv[1] != 'test':
294 sys.exit()
295
296
301
302 test_get_fhx()
303
304
305