UNPKG

11.8 kBJavaScriptView Raw
1/*
2
3 ----------------------------------------------------------------------------
4 | qewd-ripple: QEWD-based Middle Tier for Ripple OSI |
5 | |
6 | Copyright (c) 2016-17 Ripple Foundation Community Interest Company |
7 | All rights reserved. |
8 | |
9 | http://rippleosi.org |
10 | Email: code.custodian@rippleosi.org |
11 | |
12 | Author: Rob Tweed, M/Gateway Developments Ltd |
13 | |
14 | Licensed under the Apache License, Version 2.0 (the "License"); |
15 | you may not use this file except in compliance with the License. |
16 | You may obtain a copy of the License at |
17 | |
18 | http://www.apache.org/licenses/LICENSE-2.0 |
19 | |
20 | Unless required by applicable law or agreed to in writing, software |
21 | distributed under the License is distributed on an "AS IS" BASIS, |
22 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
23 | See the License for the specific language governing permissions and |
24 | limitations under the License. |
25 ----------------------------------------------------------------------------
26
27 21 June 2017
28
29*/
30
31var mySQL = require('./mySQL');
32var template = require('qewd-template');
33var dateTime = require('./dateTime');
34
35var count;
36
37function getDepartments(callback) {
38 var deptsCache = new this.documentStore.DocumentNode('rippleMedicalDepts');
39
40 var query = 'SELECT * FROM medical_departments';
41 mySQL.query(query, function(depts) {
42 if(depts.error) {
43 callback(depts.error);
44 return;
45 }
46 depts.forEach(function(dept) {
47 deptsCache.$(dept.id).setDocument(dept);
48 });
49 if (callback) callback();
50 });
51}
52
53function getGPs(callback) {
54 var gpCache = new this.documentStore.DocumentNode('rippleGPs');
55
56 var query = 'SELECT * FROM general_practitioners';
57 mySQL.query(query, function(gps) {
58 if(gps.error) {
59 callback(gps.error);
60 return;
61 }
62 gps.forEach(function(gp) {
63 gpCache.$(gp.id).setDocument(gp);
64 });
65 if (callback) callback();
66 });
67}
68
69function formatPatientData(row) {
70
71 var gpCache = new this.documentStore.DocumentNode('rippleGPs');
72 var deptCache = new this.documentStore.DocumentNode('rippleMedicalDepts');
73 var gpData = gpCache.$(row.gp_id);
74 var gp = gpData.getDocument();
75
76 var patient = {};
77 patient.id = row.nhs_number;
78 patient.nhsNumber = row.nhs_number;
79 patient.name = row.first_name + ' ' + row.last_name;
80 patient.address = formatAddressData(row.address_1, row.address_2, row.address_3, row.address_4, row.address_5, row.postcode);
81 patient.dateOfBirth = new Date(row.date_of_birth).getTime();
82 patient.gender = row.gender || '';
83 patient.phone = row.phone || '';
84 patient.gpName = gp.gp_name || '';
85 patient.gpAddress = formatAddressData(gp.address_1, gp.address_2, gp.address_3, gp.address_4, gp.address_5, gp.postcode);
86 patient.pasNo = row.pas_number || '';
87 patient.department = deptCache.$([row.department_id, 'department']).value;
88
89 return patient;
90}
91
92function formatAddressData(address_1, address_2, address_3, address_4, address_5, postcode) {
93 var address = '';
94 var comma = ' ';
95 if (address_1) {
96 address = address_1;
97 comma = ', ';
98 }
99 if (address_2) {
100 address = address + comma + address_2;
101 comma = ', ';
102 }
103 if (address_3) {
104 address = address + comma + address_3;
105 comma = ', ';
106 }
107 if (address_4) {
108 address = address + comma + address_4;
109 comma = ', ';
110 }
111 if (address_5) {
112 address = address + comma + address_5;
113 comma = ', ';
114 }
115 if (postcode) {
116 address = address + comma + postcode;
117 comma = ', ';
118 }
119
120 return address;
121}
122
123function runQuery(query, params, callback) {
124 query = template.replace(query, params);
125 console.log('** query: ' + query);
126 var self = this;
127
128 mySQL.query(query, function(rows) {
129 if(rows.error) {
130 if (callback) callback(rows);
131 return;
132 }
133 var results = [];
134 rows.forEach(function(row) {
135 results.push(formatPatientData.call(self, row));
136 });
137 if (callback) callback(results);
138 });
139}
140
141function addGenderToQuery(query, params) {
142 if (!params.sexFemale && !params.sexMale) return query;
143 var gender = 'male';
144 if (params.sexFemale) gender = 'female';
145 params.gender = gender;
146 query = query + " AND lower(P.gender) = '{{gender}}'";
147 return query;
148}
149
150function advancedSearch(params, callback) {
151
152 var surname = params.surname;
153 if (!surname || surname === '') {
154 if (callback) callback ({error: 'Missing or invalid surname'});
155 return;
156 }
157 var forename = params.forename;
158 if (!forename || forename === '') {
159 if (callback) callback ({error: 'Missing or invalid forename'});
160 return;
161 }
162
163 params.surname = surname.toString().toLowerCase();
164 params.forename = forename.toString().toLowerCase();
165
166 var count = 0;
167 for (var name in params) {
168 count++;
169 }
170
171 var query = "SELECT * FROM patients P WHERE lower(P.last_name) = '{{surname}}' AND lower(P.first_name) LIKE '{{forename}}%'";
172
173 if (count === 2) {
174 // only surname and forename prefix specified
175 return runQuery.call(this, query, params, callback);
176 }
177
178 if (params.dateOfBirth && params.dateOfBirth !== '') {
179 params.dateOfBirth = dateTime.toSqlPASFormat(params.dateOfBirth);
180 query = query + " AND P.date_of_birth = '{{dateOfBirth}}'";
181 query = addGenderToQuery(query, params);
182 return runQuery.call(this, query, params, callback);
183 }
184
185 if (params.rangeMin && params.rangeMax) {
186 var now = new Date();
187 var nowYear = now.getFullYear();
188 var fromYear = nowYear - params.rangeMax;
189 var rootDate = '-' + (now.getMonth() + 1) + '-' + now.getDate();
190 var from = fromYear + rootDate;
191 var toYear = nowYear - params.rangeMin;
192 var to = toYear + rootDate;
193 query = query + " AND P.date_of_birth >= '" + from + "' AND P.date_of_birth <= '" + to + "'";
194 query = addGenderToQuery(query, params);
195 return runQuery.call(this, query, params, callback);
196 }
197
198 query = addGenderToQuery(query, params);
199 return runQuery.call(this, query, params, callback);
200}
201
202function searchByPatient(searchString, callback) {
203 // replace any commas with a space
204 searchString = searchString.replace(/,/g , ' ');
205 // replace multiple spaces, tabs etc with a single one
206 searchString = searchString.replace(/\s\s+/g, ' ');
207 // now split up the search string into its pieces
208 var pieces = searchString.split(' ');
209
210 if (pieces.length === 0) {
211 callback({error: 'Invalid search string'});
212 return;
213 }
214
215 var firstName;
216 var lastName;
217 var nhsNumber;
218 var dateOfBirth;
219
220 if (pieces.length === 1) {
221 lastName = pieces[0];
222 firstName = '';
223 if (Number.isInteger(parseInt(lastName))) {
224 nhsNumber = lastName;
225 lastName = '';
226 firstName = '';
227 dateOfBirth = '';
228 }
229 }
230 else {
231 firstName = pieces[0];
232 lastName = pieces[1] || '';
233 dateOfBirth = pieces[2] || '';
234 }
235
236 var query;
237 if (nhsNumber) {
238 query = 'SELECT * FROM patients P WHERE P.nhs_number = \'{{nhsNumber}}\'';
239 }
240
241 else {
242 nhsNumber = '';
243
244 if (lastName === '') {
245 callback({error: 'Last Name not defined'});
246 return;
247 }
248
249 query = 'SELECT * FROM patients P WHERE P.last_name LIKE \'{{lastName}}%\'';
250 if (firstName && firstName !== '') {
251 query = query + ' AND P.first_name LIKE \'{{firstName}}%\'';
252 }
253 if (dateOfBirth && dateOfBirth !== '') {
254 query = query + ' AND P.date_of_birth = \'{{dateOfBirth}}\'';
255 }
256 //if (params.gender && params.gender !== '') {
257 // query = query + ' AND P.gender EQUALS \'{{gender}}\'';
258 //}
259 }
260
261 var params = {
262 firstName: firstName,
263 lastName: lastName,
264 dateOfBirth: dateOfBirth,
265 nhsNumber: nhsNumber
266 };
267
268 var q = this;
269 query = template.replace(query, params);
270
271 mySQL.query(query, function(rows) {
272 if(rows.error) {
273 if (callback) callback(rows);
274 return;
275 }
276 var patientDetails = [];
277 var noOfPatients = 0;
278 rows.forEach(function(row) {
279 noOfPatients++;
280 var record = formatPatientData.call(q, row);
281 var patient = {
282 source: 'local',
283 sourceId: record.id,
284 name: record.name,
285 address: record.address,
286 dateOfBirth: record.dateOfBirth,
287 gender: record.gender,
288 nhsNumber: record.nhsNumber
289 };
290 patientDetails.push(patient);
291 });
292 var results = {
293 totalPatients: noOfPatients,
294 patientDetails: patientDetails
295 };
296 if (callback) callback(results);
297 });
298}
299
300function getPatientDetails(nhsNumber, callback) {
301
302 var q = this;
303
304 var query = 'SELECT * FROM patients P WHERE P.nhs_number = ' + nhsNumber;
305 mySQL.query(query, function(patients) {
306 if(patients.error) {
307 callback(patients);
308 return;
309 }
310 var results = {};
311 patients.forEach(function(row) {
312 results[row.nhs_number] = formatPatientData.call(q, row);
313 });
314 if (callback) callback(results);
315 });
316
317}
318
319function getOnePatient(nhsNumber, callback) {
320
321 var q = this;
322
323 var getOnePatientFn = function() {
324 getPatientDetails.call(q, nhsNumber, callback);
325 };
326
327
328 count = 0;
329 getDepartments.call(this, function(error) {
330 if (error) {
331 callback({error: error});
332 return;
333 }
334 q.emit('mySQLResultsReady', getOnePatientFn);
335 });
336
337 getGPs.call(this, function(error) {
338 if (error) {
339 callback({error: error});
340 return;
341 }
342 q.emit('mySQLResultsReady', getOnePatientFn);
343 });
344
345}
346
347function getAllPatients(callback) {
348
349 var q = this;
350 var query = 'SELECT * FROM patients';
351 mySQL.query(query, function(patients) {
352 if(patients.error) {
353 callback(patients);
354 return;
355 }
356 var results = {};
357 patients.forEach(function(row) {
358 results[row.nhs_number] = formatPatientData.call(q, row);
359 });
360 if (callback) callback(results);
361 });
362}
363
364function getPatients(callback) {
365
366 var q = this;
367
368 var getAllPatientsFn = function() {
369 getAllPatients.call(q, callback);
370 };
371
372 count = 0;
373 getDepartments.call(this, function(error) {
374 if (error) {
375 callback({error: error});
376 return;
377 }
378 q.emit('mySQLResultsReady', getAllPatientsFn);
379 });
380
381 getGPs.call(this, function(error) {
382 if (error) {
383 callback({error: error});
384 return;
385 }
386 q.emit('mySQLResultsReady', getAllPatientsFn);
387 });
388
389}
390
391module.exports = {
392 init: function() {
393 var q = this;
394
395 this.on('mySQLResultsReady', function(callback) {
396 count++;
397 console.log('mySQLResultsReady event - count = ' + count);
398 if (count === 2) {
399 if (callback) callback.call(q);
400 return;
401 }
402 });
403 },
404 getPatients: getPatients,
405 advancedSearch: advancedSearch,
406 searchByPatient: searchByPatient,
407 getOnePatient: getOnePatient
408};