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