1 """GNUmed to MSVA (Canada) connector classes.
2
3 Jim's notes:
4
5 - source directory will reside on a Windows NTFS file system volume.
6 - end-of-Record will be designated by Carriage Return and Line Feed
7 - character set is "plain Western" (ISO Latin 1)
8 - record mockup:
9
10 FIRSTNAME XXLASTNAME 912345677300BC 196012251234512345M6 ADDRESS_LINE_1_XXXXXXXXXXADDRESS_LINE_2_XXXXXXXXXXCITY_XXXXXXXXXXXXXXXXXXXXBCA2A 2A2 604124456760489012340000000002009071307801
11
12 - "PHN" + "Dependent #" + "Carrier ID" (in the above example "9123456773", "00", BC") work together as an identifier
13
14 - format specification:
15
16 *-- MSVAEX30.TXT format
17 *--
18 *--------------------------------------------------------------------
19 *-- First Name X(20) No punctuations ( e.g. John Allen)
20 *-- MSP Initials X(02) e.g. JA
21 *-- Last Name X(25)
22 *-- PHN 9(10)
23 *-- Dependent # 9(02) 66 for newborn, otherwise zeros
24 *-- Carrier ID X(02) Province providing coverage:
25 *-- BC, AB, SA, MB, ON, PQ, OI, NB, NS, NL, YT, NT, NU
26 *-- Exempt X(01) "X" for exempt, otherwise blank
27 *-- Opted-out X(01) "H" for Hard (Send payment to patient address)
28 *-- "S" for Soft (Send paymant to office address)
29 *-- Blank for Opted-in
30 *-- Visits Used 9(02) # of MSP visits used this calendar year, form zero up
31 *-- to 12 0r 15 depending on age.
32 *-- Birthdate 9(08) ccyymmdd
33 *-- Payee # 9(05)
34 *-- Practitioner # 9(05)
35 *-- Sex X(01) M, F
36 *-- Chart # X(08)
37 *-- Street 1 X(25)
38 *-- Street 2 X(25)
39 *-- City X(25)
40 *-- Province X(02)
41 *-- Postal Code X(09) A0A'b'0A0 or US Zip Code
42 *-- Home Phone 9(10) If no area code use 3 leading zeros
43 *-- Work Phone 9(10) If no area code use 3 leading zeros
44 *-- SIN 9(09)
45 *-- Last Service Date 9(08) ccyymmdd
46 *-- Referral Doctor 9(05)
47 *--
48 *-- Record size = 220 + <CR><LF> = 222 End-of-Record designated by Carriage Return and Line Feed.
49 *-- File is ASCII text - Named "MSVAEX30.TXT"
50 *-- X(n) = Aplhanumeric, left justified, padded with blanks
51 *-- 9(n) = Numeric, leading zeros
52
53 A0A'b'0A0:
54
55 - standard Canadian postal code format which is 3 characters:
56 - (upper case letter + single digit number + upper case letter)
57 - followed by a breaking space
58 - followed by (number+letter number)
59
60 US Zip code:
61
62 - 12345 or 12345-1234
63
64 Dependant # / Carrier ID
65
66 I did some checking, and it seems in BC a corner case about
67 the "00" being instead "66". The provision to designate
68 newborns (as dependent "66" and, in the case of multiple
69 births, "64" ... "63") seems now obsoleted by the ability of
70 the hospital to log into the provincial system and generate
71 a new Personal Health Number. Any such legacy values in
72 Medical Manager would not be to drive the slave.
73
74 The PHN can therefore be taken as unique *within* carrier
75 ID. While the following may be far fetched, there is no
76 agreement between Canada's provinces to avoid collisions, so
77 it could be possible to exist
78
79 BC.CA MOH | Personal Health Number | 90123456780
80 ON.CA MOH | Personal Health Number | 90123456780
81
82 """
83
84 __license__ = "GPL"
85 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
86
87
88
89 import sys, io, time, datetime as pyDT
90
91
92
93 if __name__ == '__main__':
94 sys.path.insert(0, '../../')
95 from Gnumed.pycommon import gmTools, gmDateTime
96 from Gnumed.business import gmPerson
97
98 MSVA_line_len = 220
99 MSVA_dob_format = '%Y%m%d'
100 MSVA_encoding = 'latin1'
101
102
104
105 if encoding is None:
106 encoding = MSVA_encoding
107
108 pats_file = io.open(filename, mode = 'rt', encoding = encoding)
109
110 dtos = []
111
112 for line in pats_file:
113 if len(line) < MSVA_line_len:
114 continue
115
116 dto = gmPerson.cDTO_person()
117 dto.source = 'Med.Manager/CA'
118
119 dto.firstnames = '%s %s' % (
120 gmTools.capitalize(line[:20].strip(), gmTools.CAPS_FIRST_ONLY),
121 gmTools.capitalize(line[20:22].strip(), gmTools.CAPS_FIRST_ONLY)
122 )
123 dto.lastnames = gmTools.capitalize(line[22:47].strip(), gmTools.CAPS_FIRST_ONLY)
124
125 region = line[59:61]
126 dto.remember_external_id (
127 name = 'PHN (%s.CA)' % region,
128 value = line[47:57],
129 issuer = 'MOH (%s.CA)' % region
130 )
131
132 dob = time.strptime(line[65:73].strip(), MSVA_dob_format)
133 dto.dob = pyDT.datetime(dob.tm_year, dob.tm_mon, dob.tm_mday, tzinfo = gmDateTime.gmCurrentLocalTimezone)
134 dto.gender = line[83].lower()
135
136 dto.remember_external_id (
137 name = 'MM (CA) Chart #',
138 value = line[84:92],
139 issuer = 'Medical Manager (CA) application'
140 )
141
142
143 street = '%s // %s' % (
144 gmTools.capitalize(line[92:117].strip(), gmTools.CAPS_FIRST),
145 gmTools.capitalize(line[117:142].strip(), gmTools.CAPS_FIRST)
146 )
147 dto.remember_address (
148 number = '?',
149 street = street,
150 urb = line[142:167],
151 region_code = line[167:169],
152 zip = line[169:178],
153 country_code = 'CA'
154 )
155
156
157 dto.remember_comm_channel(channel = 'homephone', url = line[178:188])
158 dto.remember_comm_channel(channel = 'workphone', url = line[188:198])
159
160 dto.remember_external_id (
161 name = 'Social Insurance Number',
162 value = line[198:207],
163 issuer = 'Canada'
164 )
165
166 dtos.append(dto)
167
168 pats_file.close()
169
170 return dtos
171
172
173
174 if __name__ == "__main__":
175 from Gnumed.pycommon import gmI18N
176 gmI18N.activate_locale()
177 gmI18N.install_domain()
178 gmDateTime.init()
179
180 patfile = sys.argv[1]
181 print("reading patient data from MSVA file [%s]" % patfile)
182
183 dtos = read_persons_from_msva_file(patfile)
184 for dto in dtos:
185 print("DTO:", dto)
186 print("dto.dob:", dto.dob, type(dto.dob))
187 print("dto.dob.tz:", dto.dob.tzinfo)
188 print("dto.zip / urb / region: %s / %s / %s" % (dto.zip, dto.urb, dto.region))
189 print("dto.street:", dto.street)
190 for ext_id in dto.external_ids:
191 print(ext_id)
192 for comm in dto.comms:
193 print(comm)
194
195
196
197
198
199