1 """This module encapsulates a document stored in a GNUmed database.
2
3 @copyright: GPL v2 or later
4 """
5
6 __version__ = "$Revision: 1.118 $"
7 __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
8
9 import sys, os, shutil, os.path, types, time, logging
10
11
12 if __name__ == '__main__':
13 sys.path.insert(0, '../../')
14 from Gnumed.pycommon import gmExceptions
15 from Gnumed.pycommon import gmBusinessDBObject
16 from Gnumed.pycommon import gmPG2
17 from Gnumed.pycommon import gmTools
18 from Gnumed.pycommon import gmMimeLib
19 from Gnumed.pycommon import gmDateTime
20
21
22 _log = logging.getLogger('gm.docs')
23 _log.info(__version__)
24
25 MUGSHOT=26
26 DOCUMENT_TYPE_VISUAL_PROGRESS_NOTE = u'visual progress note'
27 DOCUMENT_TYPE_PRESCRIPTION = u'prescription'
28
30 """Represents a folder with medical documents for a single patient."""
31
33 """Fails if
34
35 - patient referenced by aPKey does not exist
36 """
37 self.pk_patient = aPKey
38 if not self._pkey_exists():
39 raise gmExceptions.ConstructorError, "No patient with PK [%s] in database." % aPKey
40
41
42
43
44
45
46
47 _log.debug('instantiated document folder for patient [%s]' % self.pk_patient)
48
51
52
53
55 """Does this primary key exist ?
56
57 - true/false/None
58 """
59
60 rows, idx = gmPG2.run_ro_queries(queries = [
61 {'cmd': u"select exists(select pk from dem.identity where pk = %s)", 'args': [self.pk_patient]}
62 ])
63 if not rows[0][0]:
64 _log.error("patient [%s] not in demographic database" % self.pk_patient)
65 return None
66 return True
67
68
69
71 cmd = u"""
72 SELECT pk_doc
73 FROM blobs.v_doc_med
74 WHERE
75 pk_patient = %(pat)s
76 AND
77 type = %(typ)s
78 AND
79 ext_ref = %(ref)s
80 ORDER BY
81 clin_when DESC
82 LIMIT 1
83 """
84 args = {
85 'pat': self.pk_patient,
86 'typ': DOCUMENT_TYPE_PRESCRIPTION,
87 'ref': u'FreeDiams'
88 }
89 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
90 if len(rows) == 0:
91 _log.info('no FreeDiams prescription available for patient [%s]' % self.pk_patient)
92 return None
93 prescription = cDocument(aPK_obj = rows[0][0])
94 return prescription
95
97 cmd = u"select pk_obj from blobs.v_latest_mugshot where pk_patient=%s"
98 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_patient]}])
99 if len(rows) == 0:
100 _log.info('no mugshots available for patient [%s]' % self.pk_patient)
101 return None
102 mugshot = cDocumentPart(aPK_obj=rows[0][0])
103 return mugshot
104
106 if latest_only:
107 cmd = u"select pk_doc, pk_obj from blobs.v_latest_mugshot where pk_patient=%s"
108 else:
109 cmd = u"""
110 select
111 vdm.pk_doc as pk_doc,
112 dobj.pk as pk_obj
113 from
114 blobs.v_doc_med vdm
115 blobs.doc_obj dobj
116 where
117 vdm.pk_type = (select pk from blobs.doc_type where name = 'patient photograph')
118 and vdm.pk_patient = %s
119 and dobj.fk_doc = vdm.pk_doc
120 """
121 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_patient]}])
122 return rows
123
125 """return flat list of document IDs"""
126
127 args = {
128 'ID': self.pk_patient,
129 'TYP': doc_type
130 }
131
132 cmd = u"""
133 select vdm.pk_doc
134 from blobs.v_doc_med vdm
135 where
136 vdm.pk_patient = %%(ID)s
137 %s
138 order by vdm.clin_when"""
139
140 if doc_type is None:
141 cmd = cmd % u''
142 else:
143 try:
144 int(doc_type)
145 cmd = cmd % u'and vdm.pk_type = %(TYP)s'
146 except (TypeError, ValueError):
147 cmd = cmd % u'and vdm.pk_type = (select pk from blobs.doc_type where name = %(TYP)s)'
148
149 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
150 doc_ids = []
151 for row in rows:
152 doc_ids.append(row[0])
153 return doc_ids
154
161
163 args = {'pat': self.pk_patient}
164 cmd = _sql_fetch_document_fields % u"""
165 pk_doc IN (
166 SELECT DISTINCT ON (b_vo.pk_doc) b_vo.pk_doc
167 FROM blobs.v_obj4doc_no_data b_vo
168 WHERE
169 pk_patient = %(pat)s
170 AND
171 reviewed IS FALSE
172 )
173 ORDER BY clin_when DESC"""
174 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
175 return [ cDocument(row = {'pk_field': 'pk_doc', 'idx': idx, 'data': r}) for r in rows ]
176
177 - def get_documents(self, doc_type=None, episodes=None, encounter=None, order_by=None, exclude_unsigned=False):
178 """Return list of documents."""
179
180 args = {
181 'pat': self.pk_patient,
182 'type': doc_type,
183 'enc': encounter
184 }
185 where_parts = [u'pk_patient = %(pat)s']
186
187 if doc_type is not None:
188 try:
189 int(doc_type)
190 where_parts.append(u'pk_type = %(type)s')
191 except (TypeError, ValueError):
192 where_parts.append(u'pk_type = (SELECT pk FROM blobs.doc_type WHERE name = %(type)s)')
193
194 if (episodes is not None) and (len(episodes) > 0):
195 where_parts.append(u'pk_episode IN %(epi)s')
196 args['epi'] = tuple(episodes)
197
198 if encounter is not None:
199 where_parts.append(u'pk_encounter = %(enc)s')
200
201 if exclude_unsigned:
202 where_parts.append(u'pk_doc IN (SELECT b_vo.pk_doc FROM blobs.v_obj4doc_no_data b_vo WHERE b_vo.pk_patient = %(pat)s AND b_vo.reviewed IS TRUE)')
203
204 if order_by is None:
205 order_by = u'ORDER BY clin_when'
206
207 cmd = u"%s\n%s" % (_sql_fetch_document_fields % u' AND '.join(where_parts), order_by)
208 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
209
210 return [ cDocument(row = {'pk_field': 'pk_doc', 'idx': idx, 'data': r}) for r in rows ]
211
212 - def add_document(self, document_type=None, encounter=None, episode=None):
213 return create_document(document_type = document_type, encounter = encounter, episode = episode)
214
215 _sql_fetch_document_part_fields = u"select * from blobs.v_obj4doc_no_data where %s"
216
218 """Represents one part of a medical document."""
219
220 _cmd_fetch_payload = _sql_fetch_document_part_fields % u"pk_obj = %s"
221 _cmds_store_payload = [
222 u"""UPDATE blobs.doc_obj SET
223 seq_idx = %(seq_idx)s,
224 comment = gm.nullify_empty_string(%(obj_comment)s),
225 filename = gm.nullify_empty_string(%(filename)s),
226 fk_intended_reviewer = %(pk_intended_reviewer)s,
227 fk_doc = %(pk_doc)s
228 WHERE
229 pk = %(pk_obj)s
230 AND
231 xmin = %(xmin_doc_obj)s
232 RETURNING
233 xmin AS xmin_doc_obj"""
234 ]
235 _updatable_fields = [
236 'seq_idx',
237 'obj_comment',
238 'pk_intended_reviewer',
239 'filename',
240 'pk_doc'
241 ]
242
243
244
245 - def export_to_file(self, aTempDir = None, aChunkSize = 0, filename=None):
246
247 if self._payload[self._idx['size']] == 0:
248 return None
249
250 if filename is None:
251 suffix = None
252
253 if self._payload[self._idx['filename']] is not None:
254 name, suffix = os.path.splitext(self._payload[self._idx['filename']])
255 suffix = suffix.strip()
256 if suffix == u'':
257 suffix = None
258
259 filename = gmTools.get_unique_filename (
260 prefix = 'gm-doc_obj-page_%s-' % self._payload[self._idx['seq_idx']],
261 suffix = suffix,
262 tmp_dir = aTempDir
263 )
264
265 success = gmPG2.bytea2file (
266 data_query = {
267 'cmd': u'SELECT substring(data from %(start)s for %(size)s) FROM blobs.doc_obj WHERE pk=%(pk)s',
268 'args': {'pk': self.pk_obj}
269 },
270 filename = filename,
271 chunk_size = aChunkSize,
272 data_size = self._payload[self._idx['size']]
273 )
274
275 if success:
276 return filename
277
278 return None
279
281 cmd = u"""
282 select
283 reviewer,
284 reviewed_when,
285 is_technically_abnormal,
286 clinically_relevant,
287 is_review_by_responsible_reviewer,
288 is_your_review,
289 coalesce(comment, '')
290 from blobs.v_reviewed_doc_objects
291 where pk_doc_obj = %s
292 order by
293 is_your_review desc,
294 is_review_by_responsible_reviewer desc,
295 reviewed_when desc
296 """
297 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}])
298 return rows
299
301 return cDocument(aPK_obj = self._payload[self._idx['pk_doc']])
302
303
304
306
307 if not (os.access(fname, os.R_OK) and os.path.isfile(fname)):
308 _log.error('[%s] is not a readable file' % fname)
309 return False
310
311 gmPG2.file2bytea (
312 query = u"UPDATE blobs.doc_obj SET data = %(data)s::bytea WHERE pk = %(pk)s",
313 filename = fname,
314 args = {'pk': self.pk_obj}
315 )
316
317
318 self.refetch_payload()
319 return True
320
321 - def set_reviewed(self, technically_abnormal=None, clinically_relevant=None):
322
323 cmd = u"""
324 select pk
325 from blobs.reviewed_doc_objs
326 where
327 fk_reviewed_row = %s and
328 fk_reviewer = (select pk from dem.staff where db_user = current_user)"""
329 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}])
330
331
332 if len(rows) == 0:
333 cols = [
334 u"fk_reviewer",
335 u"fk_reviewed_row",
336 u"is_technically_abnormal",
337 u"clinically_relevant"
338 ]
339 vals = [
340 u'%(fk_row)s',
341 u'%(abnormal)s',
342 u'%(relevant)s'
343 ]
344 args = {
345 'fk_row': self.pk_obj,
346 'abnormal': technically_abnormal,
347 'relevant': clinically_relevant
348 }
349 cmd = u"""
350 insert into blobs.reviewed_doc_objs (
351 %s
352 ) values (
353 (select pk from dem.staff where db_user=current_user),
354 %s
355 )""" % (', '.join(cols), ', '.join(vals))
356
357
358 if len(rows) == 1:
359 pk_row = rows[0][0]
360 args = {
361 'abnormal': technically_abnormal,
362 'relevant': clinically_relevant,
363 'pk_row': pk_row
364 }
365 cmd = u"""
366 update blobs.reviewed_doc_objs set
367 is_technically_abnormal = %(abnormal)s,
368 clinically_relevant = %(relevant)s
369 where
370 pk=%(pk_row)s"""
371 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
372
373 return True
374
376 if self._payload[self._idx['type']] != u'patient photograph':
377 return False
378
379 rows, idx = gmPG2.run_ro_queries (
380 queries = [{
381 'cmd': u'select coalesce(max(seq_idx)+1, 1) from blobs.doc_obj where fk_doc=%(doc_id)s',
382 'args': {'doc_id': self._payload[self._idx['pk_doc']]}
383 }]
384 )
385 self._payload[self._idx['seq_idx']] = rows[0][0]
386 self._is_modified = True
387 self.save_payload()
388
390
391 fname = self.export_to_file(aTempDir = tmpdir, aChunkSize = chunksize)
392 if fname is None:
393 return False, ''
394
395 success, msg = gmMimeLib.call_viewer_on_file(fname, block = block)
396 if not success:
397 return False, msg
398
399 return True, ''
400
401
403 cmd = u"select blobs.delete_document_part(%(pk)s, %(enc)s)"
404 args = {'pk': part_pk, 'enc': encounter_pk}
405 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
406 return
407
408 _sql_fetch_document_fields = u"""
409 SELECT
410 *,
411 COALESCE (
412 (SELECT array_agg(seq_idx) FROM blobs.doc_obj b_do WHERE b_do.fk_doc = b_vdm.pk_doc),
413 ARRAY[]::integer[]
414 )
415 AS seq_idx_list
416 FROM
417 blobs.v_doc_med b_vdm
418 WHERE
419 %s
420 """
421
422 -class cDocument(gmBusinessDBObject.cBusinessDBObject):
423 """Represents one medical document."""
424
425 _cmd_fetch_payload = _sql_fetch_document_fields % u"pk_doc = %s"
426 _cmds_store_payload = [
427 u"""update blobs.doc_med set
428 fk_type = %(pk_type)s,
429 fk_episode = %(pk_episode)s,
430 fk_encounter = %(pk_encounter)s,
431 clin_when = %(clin_when)s,
432 comment = gm.nullify_empty_string(%(comment)s),
433 ext_ref = gm.nullify_empty_string(%(ext_ref)s)
434 where
435 pk = %(pk_doc)s and
436 xmin = %(xmin_doc_med)s""",
437 u"""select xmin_doc_med from blobs.v_doc_med where pk_doc = %(pk_doc)s"""
438 ]
439
440 _updatable_fields = [
441 'pk_type',
442 'comment',
443 'clin_when',
444 'ext_ref',
445 'pk_episode',
446 'pk_encounter'
447 ]
448
450 try: del self.__has_unreviewed_parts
451 except AttributeError: pass
452
453 return super(cDocument, self).refetch_payload(ignore_changes = ignore_changes)
454
456 """Get document descriptions.
457
458 - will return a list of rows
459 """
460 if max_lng is None:
461 cmd = u"SELECT pk, text FROM blobs.doc_desc WHERE fk_doc = %s"
462 else:
463 cmd = u"SELECT pk, substring(text from 1 for %s) FROM blobs.doc_desc WHERE fk_doc=%%s" % max_lng
464 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}])
465 return rows
466
471
473 cmd = u"update blobs.doc_desc set text = %(desc)s where fk_doc = %(doc)s and pk = %(pk_desc)s"
474 gmPG2.run_rw_queries(queries = [
475 {'cmd': cmd, 'args': {'doc': self.pk_obj, 'pk_desc': pk, 'desc': description}}
476 ])
477 return True
478
480 cmd = u"delete from blobs.doc_desc where fk_doc = %(doc)s and pk = %(desc)s"
481 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'doc': self.pk_obj, 'desc': pk}}])
482 return True
483
488
489 parts = property(_get_parts, lambda x:x)
490
492 """Add a part to the document."""
493
494 cmd = u"""
495 insert into blobs.doc_obj (
496 fk_doc, data, seq_idx
497 ) VALUES (
498 %(doc_id)s,
499 ''::bytea,
500 (select coalesce(max(seq_idx)+1, 1) from blobs.doc_obj where fk_doc=%(doc_id)s)
501 )"""
502 rows, idx = gmPG2.run_rw_queries (
503 queries = [
504 {'cmd': cmd, 'args': {'doc_id': self.pk_obj}},
505 {'cmd': u"select currval('blobs.doc_obj_pk_seq')"}
506 ],
507 return_data = True
508 )
509
510 pk_part = rows[0][0]
511 new_part = cDocumentPart(aPK_obj = pk_part)
512 if not new_part.update_data_from_file(fname=file):
513 _log.error('cannot import binary data from [%s] into document part' % file)
514 gmPG2.run_rw_queries (
515 queries = [
516 {'cmd': u"delete from blobs.doc_obj where pk = %s", 'args': [pk_part]}
517 ]
518 )
519 return None
520 new_part['filename'] = file
521 new_part.save_payload()
522
523 return new_part
524
526
527 new_parts = []
528
529 for filename in files:
530 new_part = self.add_part(file = filename)
531 if new_part is None:
532 msg = 'cannot instantiate document part object'
533 _log.error(msg)
534 return (False, msg, filename)
535 new_parts.append(new_part)
536
537 if reviewer is not None:
538 new_part['pk_intended_reviewer'] = reviewer
539 success, data = new_part.save_payload()
540 if not success:
541 msg = 'cannot set reviewer to [%s]' % reviewer
542 _log.error(msg)
543 _log.error(str(data))
544 return (False, msg, filename)
545
546 return (True, '', new_parts)
547
549 fnames = []
550 for part in self.parts:
551
552 fname = os.path.basename(gmTools.coalesce (
553 part['filename'],
554 u'%s%s%s_%s' % (part['l10n_type'], gmTools.coalesce(part['ext_ref'], '-', '-%s-'), _('part'), part['seq_idx'])
555 ))
556 if export_dir is not None:
557 fname = os.path.join(export_dir, fname)
558 fnames.append(part.export_to_file(aChunkSize = chunksize, filename = fname))
559 return fnames
560
562 try:
563 return self.__has_unreviewed_parts
564 except AttributeError:
565 pass
566
567 cmd = u"SELECT EXISTS(SELECT 1 FROM blobs.v_obj4doc_no_data WHERE pk_doc = %(pk)s AND reviewed IS FALSE)"
568 args = {'pk': self.pk_obj}
569 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
570 self.__has_unreviewed_parts = rows[0][0]
571
572 return self.__has_unreviewed_parts
573
574 has_unreviewed_parts = property(_get_has_unreviewed_parts, lambda x:x)
575
576 - def set_reviewed(self, technically_abnormal=None, clinically_relevant=None):
577
578 for part in self.parts:
579 if not part.set_reviewed(technically_abnormal, clinically_relevant):
580 return False
581 return True
582
584 for part in self.parts:
585 part['pk_intended_reviewer'] = reviewer
586 success, data = part.save_payload()
587 if not success:
588 _log.error('cannot set reviewer to [%s]' % reviewer)
589 _log.error(str(data))
590 return False
591 return True
592
616
618 """Returns new document instance or raises an exception.
619 """
620 cmd = u"""INSERT INTO blobs.doc_med (fk_type, fk_encounter, fk_episode) VALUES (%(type)s, %(enc)s, %(epi)s) RETURNING pk"""
621 try:
622 int(document_type)
623 except ValueError:
624 cmd = u"""
625 INSERT INTO blobs.doc_med (
626 fk_type,
627 fk_encounter,
628 fk_episode
629 ) VALUES (
630 coalesce (
631 (SELECT pk from blobs.doc_type bdt where bdt.name = %(type)s),
632 (SELECT pk from blobs.doc_type bdt where _(bdt.name) = %(type)s)
633 ),
634 %(enc)s,
635 %(epi)s
636 ) RETURNING pk"""
637
638 args = {'type': document_type, 'enc': encounter, 'epi': episode}
639 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
640 doc = cDocument(aPK_obj = rows[0][0])
641 return doc
642
644 """Searches for documents with the given patient and type ID."""
645 if patient_id is None:
646 raise ValueError('need patient id to search for document')
647
648 args = {'pat_id': patient_id, 'type_id': type_id, 'ref': external_reference}
649 where_parts = [u'pk_patient = %(pat_id)s']
650
651 if type_id is not None:
652 where_parts.append(u'pk_type = %(type_id)s')
653
654 if external_reference is not None:
655 where_parts.append(u'ext_ref = %(ref)s')
656
657 cmd = _sql_fetch_document_fields % u' AND '.join(where_parts)
658 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
659 return [ cDocument(row = {'data': r, 'idx': idx, 'pk_field': 'pk_doc'}) for r in rows ]
660
662
663 cmd = u"SELECT blobs.delete_document(%(pk)s, %(enc)s)"
664 args = {'pk': document_id, 'enc': encounter_id}
665 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
666 if not rows[0][0]:
667 _log.error('cannot delete document [%s]', document_id)
668 return False
669 return True
670
672
673 _log.debug('reclassifying documents by type')
674 _log.debug('original: %s', original_type)
675 _log.debug('target: %s', target_type)
676
677 if target_type['pk_doc_type'] == original_type['pk_doc_type']:
678 return True
679
680 cmd = u"""
681 update blobs.doc_med set
682 fk_type = %(new_type)s
683 where
684 fk_type = %(old_type)s
685 """
686 args = {u'new_type': target_type['pk_doc_type'], u'old_type': original_type['pk_doc_type']}
687
688 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
689
690 return True
691
692
694 """Represents a document type."""
695 _cmd_fetch_payload = u"""select * from blobs.v_doc_type where pk_doc_type=%s"""
696 _cmds_store_payload = [
697 u"""update blobs.doc_type set
698 name = %(type)s
699 where
700 pk=%(pk_obj)s and
701 xmin=%(xmin_doc_type)s""",
702 u"""select xmin_doc_type from blobs.v_doc_type where pk_doc_type = %(pk_obj)s"""
703 ]
704 _updatable_fields = ['type']
705
707
708 if translation.strip() == '':
709 return False
710
711 if translation.strip() == self._payload[self._idx['l10n_type']].strip():
712 return True
713
714 rows, idx = gmPG2.run_rw_queries (
715 queries = [
716 {'cmd': u'select i18n.i18n(%s)', 'args': [self._payload[self._idx['type']]]},
717 {'cmd': u'select i18n.upd_tx((select i18n.get_curr_lang()), %(orig)s, %(tx)s)',
718 'args': {
719 'orig': self._payload[self._idx['type']],
720 'tx': translation
721 }
722 }
723 ],
724 return_data = True
725 )
726 if not rows[0][0]:
727 _log.error('cannot set translation to [%s]' % translation)
728 return False
729
730 return self.refetch_payload()
731
733 rows, idx = gmPG2.run_ro_queries (
734 queries = [{'cmd': u"SELECT * FROM blobs.v_doc_type"}],
735 get_col_idx = True
736 )
737 doc_types = []
738 for row in rows:
739 row_def = {'pk_field': 'pk_doc_type', 'idx': idx, 'data': row}
740 doc_types.append(cDocumentType(row = row_def))
741 return doc_types
742
744 args = {'typ': document_type.strip()}
745
746 cmd = u'SELECT pk FROM blobs.doc_type WHERE name = %(typ)s'
747 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
748 if len(rows) == 0:
749 cmd = u'SELECT pk FROM blobs.doc_type WHERE _(name) = %(typ)s'
750 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
751
752 if len(rows) == 0:
753 return None
754
755 return rows[0]['pk']
756
758
759 cmd = u'select pk from blobs.doc_type where name = %s'
760 rows, idx = gmPG2.run_ro_queries (
761 queries = [{'cmd': cmd, 'args': [document_type]}]
762 )
763 if len(rows) == 0:
764 cmd1 = u"INSERT INTO blobs.doc_type (name) VALUES (%s) RETURNING pk"
765 rows, idx = gmPG2.run_rw_queries (
766 queries = [{'cmd': cmd1, 'args': [document_type]}],
767 return_data = True
768 )
769 return cDocumentType(aPK_obj = rows[0][0])
770
772 if document_type['is_in_use']:
773 return False
774 gmPG2.run_rw_queries (
775 queries = [{
776 'cmd': u'delete from blobs.doc_type where pk=%s',
777 'args': [document_type['pk_doc_type']]
778 }]
779 )
780 return True
781
783 """This needs *considerably* more smarts."""
784 dirname = gmTools.get_unique_filename (
785 prefix = '',
786 suffix = time.strftime(".%Y%m%d-%H%M%S", time.localtime())
787 )
788
789 path, doc_ID = os.path.split(dirname)
790 return doc_ID
791
792
793
794 if __name__ == '__main__':
795
796 if len(sys.argv) < 2:
797 sys.exit()
798
799 if sys.argv[1] != u'test':
800 sys.exit()
801
802
804
805 print "----------------------"
806 print "listing document types"
807 print "----------------------"
808
809 for dt in get_document_types():
810 print dt
811
812 print "------------------------------"
813 print "testing document type handling"
814 print "------------------------------"
815
816 dt = create_document_type(document_type = 'dummy doc type for unit test 1')
817 print "created:", dt
818
819 dt['type'] = 'dummy doc type for unit test 2'
820 dt.save_payload()
821 print "changed base name:", dt
822
823 dt.set_translation(translation = 'Dummy-Dokumenten-Typ fuer Unit-Test')
824 print "translated:", dt
825
826 print "deleted:", delete_document_type(document_type = dt)
827
828 return
829
831
832 print "-----------------------"
833 print "testing document import"
834 print "-----------------------"
835
836 docs = search_for_documents(patient_id=12)
837 doc = docs[0]
838 print "adding to doc:", doc
839
840 fname = sys.argv[1]
841 print "adding from file:", fname
842 part = doc.add_part(file=fname)
843 print "new part:", part
844
845 return
846
857
858
859 from Gnumed.pycommon import gmI18N
860 gmI18N.activate_locale()
861 gmI18N.install_domain()
862
863
864
865 test_get_documents()
866
867
868
869
870