Package Gnumed :: Package business :: Module gmKVK
[frames] | no frames]

Source Code for Module Gnumed.business.gmKVK

  1  # -*- coding: utf-8 -*- 
  2  """GNUmed German KVK/eGK objects. 
  3   
  4  These objects handle German patient cards (KVK and eGK). 
  5   
  6  KVK: http://www.kbv.de/ita/register_G.html 
  7  eGK: http://www.gematik.de/upload/gematik_Qop_eGK_Spezifikation_Teil1_V1_1_0_Kommentare_4_1652.pdf 
  8  """ 
  9  #============================================================ 
 10  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
 11  __license__ = "GPL v2 or later" 
 12   
 13  import sys 
 14  import os 
 15  import os.path 
 16  import fileinput 
 17  import io 
 18  import time 
 19  import glob 
 20  import datetime as pyDT 
 21  import re as regex 
 22  #import simplejson as json 
 23  import logging 
 24   
 25   
 26  # our modules 
 27  if __name__ == '__main__': 
 28          sys.path.insert(0, '../../') 
 29  from Gnumed.business import gmPerson 
 30  from Gnumed.pycommon import gmExceptions, gmDateTime, gmTools, gmPG2 
 31   
 32   
 33  _log = logging.getLogger('gm.kvk') 
 34   
 35  true_egk_fields = [ 
 36          'insurance_company', 
 37          'insurance_number', 
 38          'insuree_number', 
 39          'insuree_status', 
 40          'insuree_status_detail', 
 41          'insuree_status_comment', 
 42          'title', 
 43          'firstnames', 
 44          'lastnames', 
 45          'dob', 
 46          'street', 
 47          'zip', 
 48          'urb', 
 49          'valid_since', 
 50  ] 
 51   
 52   
 53  true_kvk_fields = [ 
 54          'insurance_company', 
 55          'insurance_number', 
 56          'insurance_number_vknr', 
 57          'insuree_number', 
 58          'insuree_status', 
 59          'insuree_status_detail', 
 60          'insuree_status_comment', 
 61          'title', 
 62          'firstnames', 
 63          'name_affix', 
 64          'lastnames', 
 65          'dob', 
 66          'street', 
 67          'urb_region_code', 
 68          'zip', 
 69          'urb', 
 70          'valid_until' 
 71  ] 
 72   
 73   
 74  map_kvkd_tags2dto = { 
 75          'Version': 'libchipcard_version', 
 76          'Datum': 'last_read_date', 
 77          'Zeit': 'last_read_time', 
 78          'Lesertyp': 'reader_type', 
 79          'Kartentyp': 'card_type', 
 80          'KK-Name': 'insurance_company', 
 81          'KK-Nummer': 'insurance_number', 
 82          'KVK-Nummer': 'insurance_number_vknr', 
 83          'VKNR': 'insurance_number_vknr', 
 84          'V-Nummer': 'insuree_number', 
 85          'V-Status': 'insuree_status', 
 86          'V-Statusergaenzung': 'insuree_status_detail', 
 87          'V-Status-Erlaeuterung': 'insuree_status_comment', 
 88          'Titel': 'title', 
 89          'Vorname': 'firstnames', 
 90          'Namenszusatz': 'name_affix', 
 91          'Familienname': 'lastnames', 
 92          'Geburtsdatum': 'dob', 
 93          'Strasse': 'street', 
 94          'Laendercode': 'urb_region_code', 
 95          'PLZ': 'zip', 
 96          'Ort': 'urb', 
 97          'gueltig-seit': 'valid_since', 
 98          'gueltig-bis': 'valid_until', 
 99          'Pruefsumme-gueltig': 'crc_valid', 
100          'Kommentar': 'comment' 
101  } 
102   
103   
104  map_CCRdr_gender2gm = { 
105          'M': 'm', 
106          'W': 'f', 
107          'U': None, 
108          'D': 'h' 
109  } 
110   
111   
112  map_CCRdr_region_code2country = { 
113          'D': 'DE' 
114  } 
115   
116   
117  EXTERNAL_ID_ISSUER_TEMPLATE = '%s (%s)' 
118  EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER = 'Versichertennummer' 
119  EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER_EGK = 'Versichertennummer (eGK)' 
120   
121  #============================================================ 
122 -class cDTO_CCRdr(gmPerson.cDTO_person):
123
124 - def __init__(self, filename=None, strict=True):
125 126 gmPerson.cDTO_person.__init__(self) 127 128 self.filename = filename 129 self.date_format = '%Y%m%d' 130 self.valid_since = None 131 self.valid_until = None 132 self.card_is_rejected = False 133 self.card_is_expired = False 134 135 self.__load_vk_file()
136 137 # if we need to interpret KBV requirements by the 138 # letter we have to delete the file right here 139 #self.delete_from_source() 140 141 #-------------------------------------------------------- 142 # external API 143 #--------------------------------------------------------
144 - def get_candidate_identities(self, can_create = False):
145 old_idents = gmPerson.cDTO_person.get_candidate_identities(self, can_create = can_create) 146 147 # look for candidates based on their Insuree Number 148 if not self.card_is_rejected: 149 cmd = """ 150 SELECT pk_identity FROM dem.v_external_ids4identity WHERE 151 value = %(val)s AND 152 name = %(name)s AND 153 issuer = %(kk)s 154 """ 155 args = { 156 'val': self.insuree_number, 157 'name': '%s (%s)' % ( 158 EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER, 159 self.raw_data['Karte'] 160 ), 161 'kk': EXTERNAL_ID_ISSUER_TEMPLATE % (self.raw_data['KostentraegerName'], self.raw_data['Kostentraegerkennung']) 162 } 163 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = None) 164 165 # weed out duplicates 166 name_candidate_ids = [ o.ID for o in old_idents ] 167 for r in rows: 168 if r[0] not in name_candidate_ids: 169 old_idents.append(gmPerson.cPerson(aPK_obj = r[0])) 170 171 return old_idents
172 173 #--------------------------------------------------------
174 - def delete_from_source(self):
175 # try: 176 # os.remove(self.filename) 177 # self.filename = None 178 # except Exception: 179 # _log.exception('cannot delete CCReader file [%s]' % self.filename, verbose = False) 180 pass # for now
181 182 #--------------------------------------------------------
183 - def import_extra_data(self, identity=None, *args, **kwargs):
184 if not self.card_is_rejected: 185 args = { 186 'pat': identity.ID, 187 'dob': self.preformatted_dob, 188 'valid_until': self.valid_until, 189 'data': self.raw_data 190 } 191 cmd = """ 192 INSERT INTO de_de.insurance_card ( 193 fk_identity, 194 formatted_dob, 195 valid_until, 196 raw_data 197 ) VALUES ( 198 %(pat)s, 199 %(dob)s, 200 %(valid_until)s, 201 %(data)s 202 )""" 203 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
204 205 #-------------------------------------------------------- 206 # internal helpers 207 #--------------------------------------------------------
208 - def __load_vk_file(self):
209 210 _log.debug('loading eGK/KVK/PKVK data from [%s]', self.filename) 211 vk_file = io.open(self.filename, mode = 'rt', encoding = 'utf8') 212 self.raw_data = json.load(vk_file) 213 vk_file.close() 214 215 if self.raw_data['Fehlerbericht']['FehlerNr'] != '0x9000': 216 _log.error('error [%s] reading VK: %s', self.raw_data['Fehlerbericht']['FehlerNr'], self.raw_data['Fehlerbericht']['Fehlermeldung']) 217 raise ValueError('error [%s] reading VK: %s' % (self.raw_data['Fehlerbericht']['FehlerNr'], self.raw_data['Fehlerbericht']['Fehlermeldung'])) 218 219 # rejection 220 if self.raw_data['Ablehnen'] == 'ja': 221 self.card_is_rejected = True 222 _log.info('eGK may contain insurance information but KBV says it must be rejected because it is of generation 0') 223 224 # validity 225 # - since 226 tmp = time.strptime(self.raw_data['VersicherungsschutzBeginn'], self.date_format) 227 self.valid_since = pyDT.date(tmp.tm_year, tmp.tm_mon, tmp.tm_mday) 228 # - until 229 tmp = time.strptime(self.raw_data['VersicherungsschutzEnde'], self.date_format) 230 self.valid_until = pyDT.date(tmp.tm_year, tmp.tm_mon, tmp.tm_mday) 231 if self.valid_until < pyDT.date.today(): 232 self.card_is_expired = True 233 234 # DTO source 235 src_attrs = [] 236 if self.card_is_expired: 237 src_attrs.append(_('expired')) 238 if self.card_is_rejected: 239 _log.info('eGK contains insurance information but KBV says it must be rejected because it is of generation 0') 240 src_attrs.append(_('rejected')) 241 src_attrs.append('CCReader') 242 self.source = '%s (%s)' % ( 243 self.raw_data['Karte'], 244 ', '.join(src_attrs) 245 ) 246 247 # name / gender 248 self.firstnames = self.raw_data['Vorname'] 249 self.lastnames = self.raw_data['Nachname'] 250 self.gender = map_CCRdr_gender2gm[self.raw_data['Geschlecht']] 251 252 # title 253 title_parts = [] 254 for part in ['Titel', 'Namenszusatz', 'Vorsatzwort']: 255 tmp = self.raw_data[part].strip() 256 if tmp == '': 257 continue 258 title_parts.append(tmp) 259 if len(title_parts) > 0: 260 self.title = ' '.join(title_parts) 261 262 # dob 263 dob_str = self.raw_data['Geburtsdatum'] 264 year_str = dob_str[:4] 265 month_str = dob_str[4:6] 266 day_str = dob_str[6:8] 267 self.preformatted_dob = '%s.%s.%s' % (day_str, month_str, year_str) # pre-format for printing including "0"-parts 268 if year_str == '0000': 269 self.dob = None # redundant but explicit is good 270 else: 271 if day_str == '00': 272 self.dob_is_estimated = True 273 day_str = '01' 274 if month_str == '00': 275 self.dob_is_estimated = True 276 month_str = '01' 277 dob_str = year_str + month_str + day_str 278 tmp = time.strptime(dob_str, self.date_format) 279 self.dob = pyDT.datetime(tmp.tm_year, tmp.tm_mon, tmp.tm_mday, 11, 11, 11, 111, tzinfo = gmDateTime.gmCurrentLocalTimezone) 280 281 # addresses 282 # - street 283 try: 284 adr = self.raw_data['StrassenAdresse'] 285 try: 286 self.remember_address ( 287 adr_type = 'eGK (Wohnadresse)', 288 number = adr['Hausnummer'], 289 subunit = adr['Anschriftenzusatz'], 290 street = adr['Strasse'], 291 urb = adr['Ort'], 292 region_code = '', 293 zip = adr['Postleitzahl'], 294 country_code = map_CCRdr_region_code2country[adr['Wohnsitzlaendercode']] 295 ) 296 except ValueError: 297 _log.exception('invalid street address on card') 298 except KeyError: 299 _log.error('unknown country code [%s] on card in street address', adr['Wohnsitzlaendercode']) 300 except KeyError: 301 _log.warning('no street address on card') 302 # PO Box 303 try: 304 adr = self.raw_data['PostfachAdresse'] 305 try: 306 self.remember_address ( 307 adr_type = 'eGK (Postfach)', 308 number = adr['Postfach'], 309 #subunit = adr['Anschriftenzusatz'], 310 street = _('PO Box'), 311 urb = adr['PostfachOrt'], 312 region_code = '', 313 zip = adr['PostfachPLZ'], 314 country_code = map_CCRdr_region_code2country[adr['PostfachWohnsitzlaendercode']] 315 ) 316 except ValueError: 317 _log.exception('invalid PO Box address on card') 318 except KeyError: 319 _log.error('unknown country code [%s] on card in PO Box address', adr['Wohnsitzlaendercode']) 320 except KeyError: 321 _log.warning('no PO Box address on card') 322 323 if not (self.card_is_expired or self.card_is_rejected): 324 self.insuree_number = None 325 try: 326 self.insuree_number = self.raw_data['Versicherten_ID'] 327 except KeyError: 328 pass 329 try: 330 self.insuree_number = self.raw_data['Versicherten_ID_KVK'] 331 except KeyError: 332 pass 333 try: 334 self.insuree_number = self.raw_data['Versicherten_ID_PKV'] 335 except KeyError: 336 pass 337 if self.insuree_number is not None: 338 try: 339 self.remember_external_id ( 340 name = '%s (%s)' % ( 341 EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER, 342 self.raw_data['Karte'] 343 ), 344 value = self.insuree_number, 345 issuer = EXTERNAL_ID_ISSUER_TEMPLATE % (self.raw_data['KostentraegerName'], self.raw_data['Kostentraegerkennung']), 346 comment = 'Nummer (eGK) des Versicherten bei der Krankenkasse, gültig: %s - %s' % ( 347 gmDateTime.pydt_strftime(self.valid_since, '%Y %b %d'), 348 gmDateTime.pydt_strftime(self.valid_until, '%Y %b %d') 349 ) 350 ) 351 except KeyError: 352 _log.exception('no insurance information on eGK')
353 354 #============================================================
355 -class cDTO_eGK(gmPerson.cDTO_person):
356 357 kvkd_card_id_string = 'Elektronische Gesundheitskarte' 358
359 - def __init__(self, filename=None, strict=True):
360 self.card_type = 'eGK' 361 self.dob_format = '%d%m%Y' 362 self.valid_since_format = '%d%m%Y' 363 self.last_read_time_format = '%H:%M:%S' 364 self.last_read_date_format = '%d.%m.%Y' 365 self.filename = filename 366 367 self.__parse_egk_file(strict = strict)
368 369 # if we need to interpret KBV requirements by the 370 # letter we have to delete the file right here 371 #self.delete_from_source() 372 #-------------------------------------------------------- 373 # external API 374 #--------------------------------------------------------
375 - def get_candidate_identities(self, can_create = False):
376 old_idents = gmPerson.cDTO_person.get_candidate_identities(self, can_create = can_create) 377 378 cmd = """ 379 select pk_identity from dem.v_external_ids4identity where 380 value = %(val)s and 381 name = %(name)s and 382 issuer = %(kk)s 383 """ 384 args = { 385 'val': self.insuree_number, 386 'name': EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER, 387 'kk': EXTERNAL_ID_ISSUER_TEMPLATE % (self.insurance_company, self.insurance_number) 388 } 389 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 390 391 # weed out duplicates 392 new_idents = [] 393 for r in rows: 394 for oid in old_idents: 395 if r[0] == oid.ID: 396 break 397 new_idents.append(gmPerson.cPerson(aPK_obj = r['pk_identity'])) 398 399 old_idents.extend(new_idents) 400 401 return old_idents
402 #--------------------------------------------------------
403 - def import_extra_data(self, identity=None, *args, **kwargs):
404 # FIXME: rather use remember_external_id() 405 406 # Versicherungsnummer 407 identity.add_external_id ( 408 type_name = EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER_EGK, 409 value = self.insuree_number, 410 issuer = EXTERNAL_ID_ISSUER_TEMPLATE % (self.insurance_company, self.insurance_number), 411 comment = 'Nummer (eGK) des Versicherten bei der Krankenkasse' 412 ) 413 # address 414 street = self.street 415 number = regex.findall(' \d+.*', street) 416 if len(number) == 0: 417 number = None 418 else: 419 street = street.replace(number[0], '') 420 number = number[0].strip() 421 identity.link_address ( 422 number = number, 423 street = street, 424 postcode = self.zip, 425 urb = self.urb, 426 region_code = '', # actually: map urb2region ? 427 country_code = 'DE' # actually: map urb+region2country_code 428 )
429 # FIXME: eGK itself 430 #--------------------------------------------------------
431 - def delete_from_source(self):
432 try: 433 os.remove(self.filename) 434 self.filename = None 435 except Exception: 436 _log.exception('cannot delete kvkd file [%s]' % self.filename, verbose = False)
437 #-------------------------------------------------------- 438 # internal helpers 439 #--------------------------------------------------------
440 - def __parse_egk_file(self, strict=True):
441 442 _log.debug('parsing eGK data in [%s]', self.filename) 443 444 egk_file = io.open(self.filename, mode = 'rt', encoding = 'utf8') 445 446 card_type_seen = False 447 for line in egk_file: 448 line = line.replace('\n', '').replace('\r', '') 449 tag, content = line.split(':', 1) 450 content = content.strip() 451 452 if tag == 'Kartentyp': 453 card_type_seen = True 454 if content != cDTO_eGK.kvkd_card_id_string: 455 _log.error('parsing wrong card type') 456 _log.error('found : %s', content) 457 _log.error('expected: %s', cDTO_KVK.kvkd_card_id_string) 458 if strict: 459 raise ValueError('wrong card type: %s, expected %s', content, cDTO_KVK.kvkd_card_id_string) 460 else: 461 _log.debug('trying to parse anyway') 462 463 if tag == 'Geburtsdatum': 464 tmp = time.strptime(content, self.dob_format) 465 content = pyDT.datetime(tmp.tm_year, tmp.tm_mon, tmp.tm_mday, tzinfo = gmDateTime.gmCurrentLocalTimezone) 466 467 try: 468 setattr(self, map_kvkd_tags2dto[tag], content) 469 except KeyError: 470 _log.exception('unknown KVKd eGK file key [%s]' % tag) 471 472 # valid_since -> valid_since_timestamp 473 ts = time.strptime ( 474 '%s20%s' % (self.valid_since[:4], self.valid_since[4:]), 475 self.valid_since_format 476 ) 477 478 # last_read_date and last_read_time -> last_read_timestamp 479 ts = time.strptime ( 480 '%s %s' % (self.last_read_date, self.last_read_time), 481 '%s %s' % (self.last_read_date_format, self.last_read_time_format) 482 ) 483 self.last_read_timestamp = pyDT.datetime(ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, tzinfo = gmDateTime.gmCurrentLocalTimezone) 484 485 # guess gender from firstname 486 self.gender = gmTools.coalesce(gmPerson.map_firstnames2gender(firstnames=self.firstnames), 'f') 487 488 if not card_type_seen: 489 _log.warning('no line with card type found, unable to verify')
490 491 #============================================================
492 -class cDTO_KVK(gmPerson.cDTO_person):
493 494 kvkd_card_id_string = 'Krankenversichertenkarte' 495
496 - def __init__(self, filename=None, strict=True):
497 self.card_type = 'KVK' 498 self.dob_format = '%d%m%Y' 499 self.valid_until_format = '%d%m%Y' 500 self.last_read_time_format = '%H:%M:%S' 501 self.last_read_date_format = '%d.%m.%Y' 502 self.filename = filename 503 504 self.__parse_kvk_file(strict = strict)
505 506 # if we need to interpret KBV requirements by the 507 # letter we have to delete the file right here 508 #self.delete_from_source() 509 #-------------------------------------------------------- 510 # external API 511 #--------------------------------------------------------
512 - def get_candidate_identities(self, can_create = False):
513 old_idents = gmPerson.cDTO_person.get_candidate_identities(self, can_create = can_create) 514 515 cmd = """ 516 select pk_identity from dem.v_external_ids4identity where 517 value = %(val)s and 518 name = %(name)s and 519 issuer = %(kk)s 520 """ 521 args = { 522 'val': self.insuree_number, 523 'name': EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER, 524 'kk': EXTERNAL_ID_ISSUER_TEMPLATE % (self.insurance_company, self.insurance_number) 525 } 526 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 527 528 # weed out duplicates 529 new_idents = [] 530 for r in rows: 531 for oid in old_idents: 532 if r[0] == oid.ID: 533 break 534 new_idents.append(gmPerson.cPerson(aPK_obj = r['pk_identity'])) 535 536 old_idents.extend(new_idents) 537 538 return old_idents
539 #--------------------------------------------------------
540 - def import_extra_data(self, identity=None, *args, **kwargs):
541 # Versicherungsnummer 542 identity.add_external_id ( 543 type_name = EXTERNAL_ID_TYPE_VK_INSUREE_NUMBER, 544 value = self.insuree_number, 545 issuer = EXTERNAL_ID_ISSUER_TEMPLATE % (self.insurance_company, self.insurance_number), 546 comment = 'Nummer des Versicherten bei der Krankenkasse' 547 ) 548 # address 549 street = self.street 550 number = regex.findall(' \d+.*', street) 551 if len(number) == 0: 552 number = None 553 else: 554 street = street.replace(number[0], '') 555 number = number[0].strip() 556 identity.link_address ( 557 number = number, 558 street = street, 559 postcode = self.zip, 560 urb = self.urb, 561 region_code = '', 562 country_code = 'DE' # actually: map urb_region_code 563 )
564 # FIXME: kvk itself 565 #--------------------------------------------------------
566 - def delete_from_source(self):
567 try: 568 os.remove(self.filename) 569 self.filename = None 570 except Exception: 571 _log.exception('cannot delete kvkd file [%s]' % self.filename, verbose = False)
572 #-------------------------------------------------------- 573 # internal helpers 574 #--------------------------------------------------------
575 - def __parse_kvk_file(self, strict=True):
576 577 _log.debug('parsing KVK data in [%s]', self.filename) 578 579 kvk_file = io.open(self.filename, mode = 'rt', encoding = 'utf8') 580 581 card_type_seen = False 582 for line in kvk_file: 583 line = line.replace('\n', '').replace('\r', '') 584 tag, content = line.split(':', 1) 585 content = content.strip() 586 587 if tag == 'Kartentyp': 588 card_type_seen = True 589 if content != cDTO_KVK.kvkd_card_id_string: 590 _log.error('parsing wrong card type') 591 _log.error('found : %s', content) 592 _log.error('expected: %s', cDTO_KVK.kvkd_card_id_string) 593 if strict: 594 raise ValueError('wrong card type: %s, expected %s', content, cDTO_KVK.kvkd_card_id_string) 595 else: 596 _log.debug('trying to parse anyway') 597 598 if tag == 'Geburtsdatum': 599 tmp = time.strptime(content, self.dob_format) 600 content = pyDT.datetime(tmp.tm_year, tmp.tm_mon, tmp.tm_mday, tzinfo = gmDateTime.gmCurrentLocalTimezone) 601 602 try: 603 setattr(self, map_kvkd_tags2dto[tag], content) 604 except KeyError: 605 _log.exception('unknown KVKd kvk file key [%s]' % tag) 606 607 # valid_until -> valid_until_timestamp 608 ts = time.strptime ( 609 '28%s20%s' % (self.valid_until[:2], self.valid_until[2:]), 610 self.valid_until_format 611 ) 612 613 # last_read_date and last_read_time -> last_read_timestamp 614 ts = time.strptime ( 615 '%s %s' % (self.last_read_date, self.last_read_time), 616 '%s %s' % (self.last_read_date_format, self.last_read_time_format) 617 ) 618 self.last_read_timestamp = pyDT.datetime(ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, tzinfo = gmDateTime.gmCurrentLocalTimezone) 619 620 # guess gender from firstname 621 self.gender = gmTools.coalesce(gmPerson.map_firstnames2gender(firstnames=self.firstnames), 'f') 622 623 if not card_type_seen: 624 _log.warning('no line with card type found, unable to verify')
625 #============================================================
626 -def detect_card_type(card_file=None):
627 628 data_file = io.open(card_file, mode = 'rt', encoding = 'utf8') 629 630 for line in kvk_file: 631 line = line.replace('\n', '').replace('\r', '') 632 tag, content = line.split(':', 1) 633 content = content.strip() 634 635 if tag == 'Kartentyp': 636 pass
637 #============================================================
638 -def get_available_kvks_as_dtos(spool_dir = None):
639 640 kvk_files = glob.glob(os.path.join(spool_dir, 'KVK-*.dat')) 641 dtos = [] 642 for kvk_file in kvk_files: 643 try: 644 dto = cDTO_KVK(filename = kvk_file) 645 except Exception: 646 _log.exception('probably not a KVKd KVK file: [%s]' % kvk_file) 647 continue 648 dtos.append(dto) 649 650 return dtos
651 #------------------------------------------------------------
652 -def get_available_egks_as_dtos(spool_dir = None):
653 654 egk_files = glob.glob(os.path.join(spool_dir, 'eGK-*.dat')) 655 dtos = [] 656 for egk_file in egk_files: 657 try: 658 dto = cDTO_eGK(filename = egk_file) 659 except Exception: 660 _log.exception('probably not a KVKd eGK file: [%s]' % egk_file) 661 continue 662 dtos.append(dto) 663 664 return dtos
665 #------------------------------------------------------------
666 -def get_available_CCRdr_files_as_dtos(spool_dir = None):
667 668 ccrdr_files = glob.glob(os.path.join(spool_dir, 'CCReader-*.dat')) 669 dtos = [] 670 for ccrdr_file in ccrdr_files: 671 try: 672 dto = cDTO_CCRdr(filename = ccrdr_file) 673 except Exception: 674 _log.exception('probably not a CCReader file: [%s]' % ccrdr_file) 675 continue 676 dtos.append(dto) 677 678 return dtos
679 #------------------------------------------------------------
680 -def get_available_cards_as_dtos(spool_dir = None):
681 dtos = [] 682 # dtos.extend(get_available_CCRdr_files_as_dtos(spool_dir = spool_dir)) 683 dtos.extend(get_available_kvks_as_dtos(spool_dir = spool_dir)) 684 dtos.extend(get_available_egks_as_dtos(spool_dir = spool_dir)) 685 686 return dtos
687 688 #============================================================ 689 # main 690 #------------------------------------------------------------ 691 if __name__ == "__main__": 692 693 from Gnumed.pycommon import gmI18N 694 695 gmI18N.activate_locale() 696 gmDateTime.init() 697
698 - def test_vks():
699 dtos = get_available_CCRdr_files_as_dtos(spool_dir = sys.argv[2]) 700 for dto in dtos: 701 print(dto)
702
703 - def test_egk_dto():
704 # test cKVKd_file object 705 kvkd_file = sys.argv[2] 706 print("reading eGK data from KVKd file", kvkd_file) 707 dto = cDTO_eGK(filename = kvkd_file, strict = False) 708 print(dto) 709 for attr in true_egk_fields: 710 print(getattr(dto, attr))
711
712 - def test_kvk_dto():
713 # test cKVKd_file object 714 kvkd_file = sys.argv[2] 715 print("reading KVK data from KVKd file", kvkd_file) 716 dto = cDTO_KVK(filename = kvkd_file, strict = False) 717 print(dto) 718 for attr in true_kvk_fields: 719 print(getattr(dto, attr))
720
721 - def test_get_available_kvks_as_dto():
722 dtos = get_available_kvks_as_dtos(spool_dir = sys.argv[2]) 723 for dto in dtos: 724 print(dto)
725 726 if (len(sys.argv)) > 1 and (sys.argv[1] == 'test'): 727 if len(sys.argv) < 3: 728 print("give name of KVKd file as first argument") 729 sys.exit(-1) 730 test_vks() 731 #test_egk_dto() 732 #test_kvk_dto() 733 #test_get_available_kvks_as_dto() 734 735 #============================================================ 736 # docs 737 #------------------------------------------------------------ 738 # name | mandat | type | length | format 739 # -------------------------------------------- 740 # Name Kasse | x | str | 2-28 741 # Nr. Kasse | x | int | 7 742 # VKNR | | int | 5 # MUST be derived from Stammdaten-file, not from KVK 743 # Nr. Pat | x | int | 6-12 744 # Status Pat | x | str | 1 or 4 745 # Statuserg. | | str | 1-3 746 # Titel Pat | | str | 3-15 747 # Vorname | | str | 2-28 748 # Adelspraed.| | str | 1-15 749 # Nachname | x | str | 2-28 750 # geboren | x | int | 8 | DDMMYYYY 751 # Straße | | str | 1-28 752 # Ländercode | | str | 1-3 753 # PLZ | x | int | 4-7 754 # Ort | x | str | 2-23 755 # gültig bis | | int | 4 | MMYY 756