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 where
230 pk=%(pk_obj)s and
231 xmin=%(xmin_doc_obj)s""",
232 u"""select xmin_doc_obj from blobs.v_obj4doc_no_data where pk_obj = %(pk_obj)s"""
233 ]
234 _updatable_fields = [
235 'seq_idx',
236 'obj_comment',
237 'pk_intended_reviewer',
238 'filename'
239 ]
240
241
242
243 - def export_to_file(self, aTempDir = None, aChunkSize = 0, filename=None):
244
245 if self._payload[self._idx['size']] == 0:
246 return None
247
248 if filename is None:
249 suffix = None
250
251 if self._payload[self._idx['filename']] is not None:
252 name, suffix = os.path.splitext(self._payload[self._idx['filename']])
253 suffix = suffix.strip()
254 if suffix == u'':
255 suffix = None
256
257 filename = gmTools.get_unique_filename (
258 prefix = 'gm-doc_obj-page_%s-' % self._payload[self._idx['seq_idx']],
259 suffix = suffix,
260 tmp_dir = aTempDir
261 )
262
263 success = gmPG2.bytea2file (
264 data_query = {
265 'cmd': u'SELECT substring(data from %(start)s for %(size)s) FROM blobs.doc_obj WHERE pk=%(pk)s',
266 'args': {'pk': self.pk_obj}
267 },
268 filename = filename,
269 chunk_size = aChunkSize,
270 data_size = self._payload[self._idx['size']]
271 )
272
273 if success:
274 return filename
275
276 return None
277
279 cmd = u"""
280 select
281 reviewer,
282 reviewed_when,
283 is_technically_abnormal,
284 clinically_relevant,
285 is_review_by_responsible_reviewer,
286 is_your_review,
287 coalesce(comment, '')
288 from blobs.v_reviewed_doc_objects
289 where pk_doc_obj = %s
290 order by
291 is_your_review desc,
292 is_review_by_responsible_reviewer desc,
293 reviewed_when desc
294 """
295 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}])
296 return rows
297
299 return cDocument(aPK_obj = self._payload[self._idx['pk_doc']])
300
301
302
304
305 if not (os.access(fname, os.R_OK) and os.path.isfile(fname)):
306 _log.error('[%s] is not a readable file' % fname)
307 return False
308
309 gmPG2.file2bytea (
310 query = u"UPDATE blobs.doc_obj SET data=%(data)s::bytea WHERE pk=%(pk)s",
311 filename = fname,
312 args = {'pk': self.pk_obj}
313 )
314
315
316 self.refetch_payload()
317 return True
318
319 - def set_reviewed(self, technically_abnormal=None, clinically_relevant=None):
320
321 cmd = u"""
322 select pk
323 from blobs.reviewed_doc_objs
324 where
325 fk_reviewed_row = %s and
326 fk_reviewer = (select pk from dem.staff where db_user = current_user)"""
327 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}])
328
329
330 if len(rows) == 0:
331 cols = [
332 u"fk_reviewer",
333 u"fk_reviewed_row",
334 u"is_technically_abnormal",
335 u"clinically_relevant"
336 ]
337 vals = [
338 u'%(fk_row)s',
339 u'%(abnormal)s',
340 u'%(relevant)s'
341 ]
342 args = {
343 'fk_row': self.pk_obj,
344 'abnormal': technically_abnormal,
345 'relevant': clinically_relevant
346 }
347 cmd = u"""
348 insert into blobs.reviewed_doc_objs (
349 %s
350 ) values (
351 (select pk from dem.staff where db_user=current_user),
352 %s
353 )""" % (', '.join(cols), ', '.join(vals))
354
355
356 if len(rows) == 1:
357 pk_row = rows[0][0]
358 args = {
359 'abnormal': technically_abnormal,
360 'relevant': clinically_relevant,
361 'pk_row': pk_row
362 }
363 cmd = u"""
364 update blobs.reviewed_doc_objs set
365 is_technically_abnormal = %(abnormal)s,
366 clinically_relevant = %(relevant)s
367 where
368 pk=%(pk_row)s"""
369 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
370
371 return True
372
374 if self._payload[self._idx['type']] != u'patient photograph':
375 return False
376
377 rows, idx = gmPG2.run_ro_queries (
378 queries = [{
379 'cmd': u'select coalesce(max(seq_idx)+1, 1) from blobs.doc_obj where fk_doc=%(doc_id)s',
380 'args': {'doc_id': self._payload[self._idx['pk_doc']]}
381 }]
382 )
383 self._payload[self._idx['seq_idx']] = rows[0][0]
384 self._is_modified = True
385 self.save_payload()
386
388
389 fname = self.export_to_file(aTempDir = tmpdir, aChunkSize = chunksize)
390 if fname is None:
391 return False, ''
392
393 success, msg = gmMimeLib.call_viewer_on_file(fname, block = block)
394 if not success:
395 return False, msg
396
397 return True, ''
398
399 _sql_fetch_document_fields = u"""
400 SELECT
401 *,
402 COALESCE (
403 (SELECT array_agg(seq_idx) FROM blobs.doc_obj b_do WHERE b_do.fk_doc = b_vdm.pk_doc),
404 ARRAY[]::integer[]
405 )
406 AS seq_idx_list
407 FROM
408 blobs.v_doc_med b_vdm
409 WHERE
410 %s
411 """
412
413 -class cDocument(gmBusinessDBObject.cBusinessDBObject):
414 """Represents one medical document."""
415
416 _cmd_fetch_payload = _sql_fetch_document_fields % u"pk_doc = %s"
417 _cmds_store_payload = [
418 u"""update blobs.doc_med set
419 fk_type = %(pk_type)s,
420 fk_episode = %(pk_episode)s,
421 fk_encounter = %(pk_encounter)s,
422 clin_when = %(clin_when)s,
423 comment = gm.nullify_empty_string(%(comment)s),
424 ext_ref = gm.nullify_empty_string(%(ext_ref)s)
425 where
426 pk = %(pk_doc)s and
427 xmin = %(xmin_doc_med)s""",
428 u"""select xmin_doc_med from blobs.v_doc_med where pk_doc = %(pk_doc)s"""
429 ]
430
431 _updatable_fields = [
432 'pk_type',
433 'comment',
434 'clin_when',
435 'ext_ref',
436 'pk_episode',
437 'pk_encounter'
438 ]
439
441 try: del self.__has_unreviewed_parts
442 except AttributeError: pass
443
444 return super(cDocument, self).refetch_payload(ignore_changes = ignore_changes)
445
447 """Get document descriptions.
448
449 - will return a list of rows
450 """
451 if max_lng is None:
452 cmd = u"SELECT pk, text FROM blobs.doc_desc WHERE fk_doc = %s"
453 else:
454 cmd = u"SELECT pk, substring(text from 1 for %s) FROM blobs.doc_desc WHERE fk_doc=%%s" % max_lng
455 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [self.pk_obj]}])
456 return rows
457
462
464 cmd = u"update blobs.doc_desc set text = %(desc)s where fk_doc = %(doc)s and pk = %(pk_desc)s"
465 gmPG2.run_rw_queries(queries = [
466 {'cmd': cmd, 'args': {'doc': self.pk_obj, 'pk_desc': pk, 'desc': description}}
467 ])
468 return True
469
471 cmd = u"delete from blobs.doc_desc where fk_doc = %(doc)s and pk = %(desc)s"
472 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'doc': self.pk_obj, 'desc': pk}}])
473 return True
474
479
480 parts = property(_get_parts, lambda x:x)
481
483 """Add a part to the document."""
484
485 cmd = u"""
486 insert into blobs.doc_obj (
487 fk_doc, data, seq_idx
488 ) VALUES (
489 %(doc_id)s,
490 ''::bytea,
491 (select coalesce(max(seq_idx)+1, 1) from blobs.doc_obj where fk_doc=%(doc_id)s)
492 )"""
493 rows, idx = gmPG2.run_rw_queries (
494 queries = [
495 {'cmd': cmd, 'args': {'doc_id': self.pk_obj}},
496 {'cmd': u"select currval('blobs.doc_obj_pk_seq')"}
497 ],
498 return_data = True
499 )
500
501 pk_part = rows[0][0]
502 new_part = cDocumentPart(aPK_obj = pk_part)
503 if not new_part.update_data_from_file(fname=file):
504 _log.error('cannot import binary data from [%s] into document part' % file)
505 gmPG2.run_rw_queries (
506 queries = [
507 {'cmd': u"delete from blobs.doc_obj where pk = %s", 'args': [pk_part]}
508 ]
509 )
510 return None
511 new_part['filename'] = file
512 new_part.save_payload()
513
514 return new_part
515
517
518 new_parts = []
519
520 for filename in files:
521 new_part = self.add_part(file = filename)
522 if new_part is None:
523 msg = 'cannot instantiate document part object'
524 _log.error(msg)
525 return (False, msg, filename)
526 new_parts.append(new_part)
527
528 if reviewer is not None:
529 new_part['pk_intended_reviewer'] = reviewer
530 success, data = new_part.save_payload()
531 if not success:
532 msg = 'cannot set reviewer to [%s]' % reviewer
533 _log.error(msg)
534 _log.error(str(data))
535 return (False, msg, filename)
536
537 return (True, '', new_parts)
538
540 fnames = []
541 for part in self.parts:
542
543 fname = os.path.basename(gmTools.coalesce (
544 part['filename'],
545 u'%s%s%s_%s' % (part['l10n_type'], gmTools.coalesce(part['ext_ref'], '-', '-%s-'), _('part'), part['seq_idx'])
546 ))
547 if export_dir is not None:
548 fname = os.path.join(export_dir, fname)
549 fnames.append(part.export_to_file(aChunkSize = chunksize, filename = fname))
550 return fnames
551
553 try:
554 return self.__has_unreviewed_parts
555 except AttributeError:
556 pass
557
558 cmd = u"SELECT EXISTS(SELECT 1 FROM blobs.v_obj4doc_no_data WHERE pk_doc = %(pk)s AND reviewed IS FALSE)"
559 args = {'pk': self.pk_obj}
560 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
561 self.__has_unreviewed_parts = rows[0][0]
562
563 return self.__has_unreviewed_parts
564
565 has_unreviewed_parts = property(_get_has_unreviewed_parts, lambda x:x)
566
567 - def set_reviewed(self, technically_abnormal=None, clinically_relevant=None):
568
569 for part in self.parts:
570 if not part.set_reviewed(technically_abnormal, clinically_relevant):
571 return False
572 return True
573
575 for part in self.parts:
576 part['pk_intended_reviewer'] = reviewer
577 success, data = part.save_payload()
578 if not success:
579 _log.error('cannot set reviewer to [%s]' % reviewer)
580 _log.error(str(data))
581 return False
582 return True
583
607
609 """Returns new document instance or raises an exception.
610 """
611 cmd = u"""INSERT INTO blobs.doc_med (fk_type, fk_encounter, fk_episode) VALUES (%(type)s, %(enc)s, %(epi)s) RETURNING pk"""
612 try:
613 int(document_type)
614 except ValueError:
615 cmd = u"""
616 INSERT INTO blobs.doc_med (
617 fk_type,
618 fk_encounter,
619 fk_episode
620 ) VALUES (
621 coalesce (
622 (SELECT pk from blobs.doc_type bdt where bdt.name = %(type)s),
623 (SELECT pk from blobs.doc_type bdt where _(bdt.name) = %(type)s)
624 ),
625 %(enc)s,
626 %(epi)s
627 ) RETURNING pk"""
628
629 args = {'type': document_type, 'enc': encounter, 'epi': episode}
630 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
631 doc = cDocument(aPK_obj = rows[0][0])
632 return doc
633
635 """Searches for documents with the given patient and type ID.
636
637 No type ID returns all documents for the patient.
638 """
639
640 if patient_id is None:
641 raise ValueError('need patient id to search for document')
642
643 args = {'pat_id': patient_id, 'type_id': type_id}
644 if type_id is None:
645 cmd = u"SELECT pk_doc from blobs.v_doc_med WHERE pk_patient = %(pat_id)s"
646 else:
647 cmd = u"SELECT pk_doc from blobs.v_doc_med WHERE pk_patient = %(pat_id)s and pk_type = %(type_id)s"
648
649 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
650
651 docs = []
652 for row in rows:
653 docs.append(cDocument(row[0]))
654 return docs
655
657
658 cmd = u"select blobs.delete_document(%(pk)s, %(enc)s)"
659 args = {'pk': document_id, 'enc': encounter_id}
660 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
661 return
662
664
665 _log.debug('reclassifying documents by type')
666 _log.debug('original: %s', original_type)
667 _log.debug('target: %s', target_type)
668
669 if target_type['pk_doc_type'] == original_type['pk_doc_type']:
670 return True
671
672 cmd = u"""
673 update blobs.doc_med set
674 fk_type = %(new_type)s
675 where
676 fk_type = %(old_type)s
677 """
678 args = {u'new_type': target_type['pk_doc_type'], u'old_type': original_type['pk_doc_type']}
679
680 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
681
682 return True
683
684
686 """Represents a document type."""
687 _cmd_fetch_payload = u"""select * from blobs.v_doc_type where pk_doc_type=%s"""
688 _cmds_store_payload = [
689 u"""update blobs.doc_type set
690 name = %(type)s
691 where
692 pk=%(pk_obj)s and
693 xmin=%(xmin_doc_type)s""",
694 u"""select xmin_doc_type from blobs.v_doc_type where pk_doc_type = %(pk_obj)s"""
695 ]
696 _updatable_fields = ['type']
697
699
700 if translation.strip() == '':
701 return False
702
703 if translation.strip() == self._payload[self._idx['l10n_type']].strip():
704 return True
705
706 rows, idx = gmPG2.run_rw_queries (
707 queries = [
708 {'cmd': u'select i18n.i18n(%s)', 'args': [self._payload[self._idx['type']]]},
709 {'cmd': u'select i18n.upd_tx((select i18n.get_curr_lang()), %(orig)s, %(tx)s)',
710 'args': {
711 'orig': self._payload[self._idx['type']],
712 'tx': translation
713 }
714 }
715 ],
716 return_data = True
717 )
718 if not rows[0][0]:
719 _log.error('cannot set translation to [%s]' % translation)
720 return False
721
722 return self.refetch_payload()
723
724
726 rows, idx = gmPG2.run_ro_queries (
727 queries = [{'cmd': u"SELECT * FROM blobs.v_doc_type"}],
728 get_col_idx = True
729 )
730 doc_types = []
731 for row in rows:
732 row_def = {
733 'pk_field': 'pk_doc_type',
734 'idx': idx,
735 'data': row
736 }
737 doc_types.append(cDocumentType(row = row_def))
738 return doc_types
739
741
742 cmd = u'select pk from blobs.doc_type where name = %s'
743 rows, idx = gmPG2.run_ro_queries (
744 queries = [{'cmd': cmd, 'args': [document_type]}]
745 )
746 if len(rows) == 0:
747 cmd1 = u"insert into blobs.doc_type (name) values (%s)"
748 cmd2 = u"select currval('blobs.doc_type_pk_seq')"
749 rows, idx = gmPG2.run_rw_queries (
750 queries = [
751 {'cmd': cmd1, 'args': [document_type]},
752 {'cmd': cmd2}
753 ],
754 return_data = True
755 )
756 return cDocumentType(aPK_obj = rows[0][0])
757
759 if document_type['is_in_use']:
760 return False
761 gmPG2.run_rw_queries (
762 queries = [{
763 'cmd': u'delete from blobs.doc_type where pk=%s',
764 'args': [document_type['pk_doc_type']]
765 }]
766 )
767 return True
768
770 """This needs *considerably* more smarts."""
771 dirname = gmTools.get_unique_filename (
772 prefix = '',
773 suffix = time.strftime(".%Y%m%d-%H%M%S", time.localtime())
774 )
775
776 path, doc_ID = os.path.split(dirname)
777 return doc_ID
778
779
780
781 if __name__ == '__main__':
782
783 if len(sys.argv) < 2:
784 sys.exit()
785
786 if sys.argv[1] != u'test':
787 sys.exit()
788
789
791
792 print "----------------------"
793 print "listing document types"
794 print "----------------------"
795
796 for dt in get_document_types():
797 print dt
798
799 print "------------------------------"
800 print "testing document type handling"
801 print "------------------------------"
802
803 dt = create_document_type(document_type = 'dummy doc type for unit test 1')
804 print "created:", dt
805
806 dt['type'] = 'dummy doc type for unit test 2'
807 dt.save_payload()
808 print "changed base name:", dt
809
810 dt.set_translation(translation = 'Dummy-Dokumenten-Typ fuer Unit-Test')
811 print "translated:", dt
812
813 print "deleted:", delete_document_type(document_type = dt)
814
815 return
816
818
819 print "-----------------------"
820 print "testing document import"
821 print "-----------------------"
822
823 docs = search_for_document(patient_id=12)
824 doc = docs[0]
825 print "adding to doc:", doc
826
827 fname = sys.argv[1]
828 print "adding from file:", fname
829 part = doc.add_part(file=fname)
830 print "new part:", part
831
832 return
833
844
845
846 from Gnumed.pycommon import gmI18N
847 gmI18N.activate_locale()
848 gmI18N.install_domain()
849
850
851
852 test_get_documents()
853
854
855
856
857