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 __version__ = "$Revision: 1.2 $"
86 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
87
88
89
90 import sys, codecs, time, datetime as pyDT
91
92
93
94 if __name__ == '__main__':
95 sys.path.insert(0, '../../')
96 from Gnumed.pycommon import gmTools, gmDateTime
97 from Gnumed.business import gmPerson
98
99 MSVA_line_len = 220
100 MSVA_dob_format = '%Y%m%d'
101 MSVA_encoding = 'latin1'
102
103
105
106 if encoding is None:
107 encoding = MSVA_encoding
108
109 pats_file = codecs.open(filename = filename, mode = 'rU', encoding = encoding)
110
111 dtos = []
112
113 for line in pats_file:
114 if len(line) < MSVA_line_len:
115 continue
116
117 dto = gmPerson.cDTO_person()
118 dto.source = u'Med.Manager/CA'
119
120 dto.firstnames = u'%s %s' % (
121 gmTools.capitalize(line[:20].strip(), gmTools.CAPS_FIRST_ONLY),
122 gmTools.capitalize(line[20:22].strip(), gmTools.CAPS_FIRST_ONLY)
123 )
124 dto.lastnames = gmTools.capitalize(line[22:47].strip(), gmTools.CAPS_FIRST_ONLY)
125
126 province = line[59:61]
127 dto.remember_external_id (
128 name = u'PHN (%s.CA)' % province,
129 value = line[47:57],
130 issuer = u'MOH (%s.CA)' % province
131 )
132
133 dob = time.strptime(line[65:73].strip(), MSVA_dob_format)
134 dto.dob = pyDT.datetime(dob.tm_year, dob.tm_mon, dob.tm_mday, tzinfo = gmDateTime.gmCurrentLocalTimezone)
135 dto.gender = line[83].lower()
136
137 dto.remember_external_id (
138 name = u'MM (CA) Chart #',
139 value = line[84:92],
140 issuer = u'Medical Manager (CA) application'
141 )
142
143
144 street = u'%s // %s' % (
145 gmTools.capitalize(line[92:117].strip(), gmTools.CAPS_FIRST),
146 gmTools.capitalize(line[117:142].strip(), gmTools.CAPS_FIRST)
147 )
148 dto.remember_address (
149 number = '?',
150 street = street,
151 urb = line[142:167],
152 region = line[167:169],
153 zip = line[169:178],
154 country = 'CA'
155 )
156
157
158 dto.remember_comm_channel(channel = u'homephone', url = line[178:188])
159 dto.remember_comm_channel(channel = u'workphone', url = line[188:198])
160
161 dto.remember_external_id (
162 name = u'Social Insurance Number',
163 value = line[198:207],
164 issuer = u'Canada'
165 )
166
167 dtos.append(dto)
168
169 pats_file.close()
170
171 return dtos
172
173
174
175 if __name__ == "__main__":
176 from Gnumed.pycommon import gmI18N
177 gmI18N.activate_locale()
178 gmI18N.install_domain()
179 gmDateTime.init()
180
181 patfile = sys.argv[1]
182 print "reading patient data from MSVA file [%s]" % patfile
183
184 dtos = read_persons_from_msva_file(patfile)
185 for dto in dtos:
186 print "DTO:", dto
187 print "dto.dob:", dto.dob, type(dto.dob)
188 print "dto.dob.tz:", dto.dob.tzinfo
189 print "dto.zip / urb / region: %s / %s / %s" % (dto.zip, dto.urb, dto.region)
190 print "dto.street:", dto.street
191 for ext_id in dto.external_ids:
192 print ext_id
193 for comm in dto.comms:
194 print comm
195
196
197
198
199
200