diff --git a/.env.development b/.env.development index bddcb7f423..fb2bb2f8b5 100644 --- a/.env.development +++ b/.env.development @@ -5,7 +5,7 @@ PORT=8080 DB_HOST='localhost' DB_USER='bhima' DB_PASS='HISCongo2013' -DB_NAME='imck' +DB_NAME='bhima_test' # session variables SESS_SECRET='XopEn BlowFISH' diff --git a/client/src/i18n/en/patient_registry.json b/client/src/i18n/en/patient_registry.json index b603760588..47551c21a5 100644 --- a/client/src/i18n/en/patient_registry.json +++ b/client/src/i18n/en/patient_registry.json @@ -12,6 +12,7 @@ "YEAR_OLD":"year old", "YEARS_OLD":"years old", "TITLE":"Patient Registry", - "RECORD":"Record" + "RECORD":"Record", + "MERGE_SUCCESS":"Patiens fusionnés avec succès" } } diff --git a/client/src/i18n/fr/patient_registry.json b/client/src/i18n/fr/patient_registry.json index aba5ea2eb0..ce774700e4 100644 --- a/client/src/i18n/fr/patient_registry.json +++ b/client/src/i18n/fr/patient_registry.json @@ -12,6 +12,7 @@ "RECORD":"Enregistrement", "YEAR_OLD":"an", "YEARS_OLD":"ans", - "TITLE":"Registre des Patients" + "TITLE":"Registre des Patients", + "MERGE_SUCCESS":"Patiens fusionnés avec succès" } } diff --git a/client/src/modules/patients/registry/modals/mergePatients.modal.js b/client/src/modules/patients/registry/modals/mergePatients.modal.js index e7941bb1c4..ae26f2ad02 100644 --- a/client/src/modules/patients/registry/modals/mergePatients.modal.js +++ b/client/src/modules/patients/registry/modals/mergePatients.modal.js @@ -2,10 +2,10 @@ angular.module('bhima.controllers') .controller('MergePatientsModalController', MergePatientsModalController); MergePatientsModalController.$inject = [ - 'PatientService', '$state', 'NotifyService', + 'PatientService', '$state', 'NotifyService', '$uibModalInstance', ]; -function MergePatientsModalController(Patients, $state, Notify) { +function MergePatientsModalController(Patients, $state, Notify, Instance) { const vm = this; vm.patients = $state.params.patients; @@ -18,12 +18,14 @@ function MergePatientsModalController(Patients, $state, Notify) { function submit() { const params = { selected : vm.selected, - other : vm.patients.filter(p => p.uuid === vm.selected).map(p => p.uuid), + other : vm.patients.filter(p => p.uuid !== vm.selected).map(p => p.uuid), }; return Patients.merge(params) - .then(res => { - console.log(res); + .then(() => { + Notify.success('PATIENT_REGISTRY.MERGE_SUCCESS'); + Instance.close(); + $state.go('patientRegistry', null, { reload : true }); }) .catch(Notify.handleError); } diff --git a/server/controllers/medical/patients/merge.js b/server/controllers/medical/patients/merge.js index 7145a8fca5..9d9c86a7d2 100644 --- a/server/controllers/medical/patients/merge.js +++ b/server/controllers/medical/patients/merge.js @@ -3,11 +3,13 @@ * one patient. * * The merge consists to : - * - get debtor_uuids of the selected patients and others + * - get debtor_uuids of the selected patient (patient to keep) and others patients (patients to remove) * - replace all occurences of debtor_uuid of patient to remove by the debtor_uuid - * of the selected patient in journal and general ledger - * - remove the not selected patient - * - recalculate period total + * of the selected patient (patient to keep) in journal and general ledger + * cash, debtor_group_history, invoice, patient, employee, patient_assignment, + * patient_document, patient_hospitalization, patient_visit + * - remove the patient to remove + * - remove the debtor relate to patient to remove */ const db = require('../../../lib/db'); @@ -17,11 +19,11 @@ function mergePatients(req, res, next) { const params = req.body; const glb = {}; - const selectedUuid = db.bid(params.selected); - const otherUuids = params.other.map(uuid => db.bid(uuid)); + const selectedPatientUuid = db.bid(params.selected); + const otherPatientUuids = params.other.map(uuid => db.bid(uuid)); const getSelectedDebtorUuid = `SELECT debtor_uuid FROM patient WHERE uuid = ?`; - const getOtherDebtorUuid = `SELECT debtor_uuid FROM patient WHERE uuid IN (?)`; + const getOtherDebtorUuids = `SELECT debtor_uuid FROM patient WHERE uuid IN (?)`; const replaceDebtorInJournal = ` UPDATE posting_journal SET entity_uuid = ? WHERE entity_uuid IN (?); @@ -48,7 +50,7 @@ function mergePatients(req, res, next) { UPDATE patient_assignment SET patient_uuid = ? WHERE patient_uuid IN (?); `; const replacePatientInPatientDocument = ` - UPDATE patient_assignment SET patient_uuid = ? WHERE patient_uuid IN (?); + UPDATE patient_document SET patient_uuid = ? WHERE patient_uuid IN (?); `; const replacePatientInPatientHospitalization = ` UPDATE patient_hospitalization SET patient_uuid = ? WHERE patient_uuid IN (?); @@ -64,38 +66,37 @@ function mergePatients(req, res, next) { DELETE FROM patient WHERE uuid IN (?); `; - db.one(getSelectedDebtorUuid, [selectedUuid]) + db.one(getSelectedDebtorUuid, [selectedPatientUuid]) .then(row => { glb.selectedDebtorUuid = row.debtor_uuid; - return db.exec(getOtherDebtorUuid, otherUuids); + return db.exec(getOtherDebtorUuids, otherPatientUuids); }) .then(rows => { glb.otherDebtorUuids = rows.map(row => row.debtor_uuid); const transaction = db.transaction(); - console.log('>>>', glb.selectedDebtorUuid, glb.otherDebtorUuids); - transaction.addQuery(replaceDebtorInJournal, [glb.selectedDebtorUuid, glb.otherDebtorUuids]); - transaction.addQuery(replaceDebtorInLedger, [glb.selectedDebtorUuid, glb.otherDebtorUuids]); - transaction.addQuery(replaceDebtorInCash, [glb.selectedDebtorUuid, glb.otherDebtorUuids]); - transaction.addQuery(replaceDebtorInDebtorGroupHistory, [glb.selectedDebtorUuid, glb.otherDebtorUuids]); - transaction.addQuery(replaceDebtorInInvoice, [glb.selectedDebtorUuid, glb.otherDebtorUuids]); - transaction.addQuery(replaceDebtorInPatient, [glb.selectedDebtorUuid, glb.otherDebtorUuids]); + transaction.addQuery(replaceDebtorInJournal, [glb.selectedDebtorUuid, [glb.otherDebtorUuids]]); + transaction.addQuery(replaceDebtorInLedger, [glb.selectedDebtorUuid, [glb.otherDebtorUuids]]); + + transaction.addQuery(replaceDebtorInCash, [glb.selectedDebtorUuid, [glb.otherDebtorUuids]]); + transaction.addQuery(replaceDebtorInDebtorGroupHistory, [glb.selectedDebtorUuid, [glb.otherDebtorUuids]]); + transaction.addQuery(replaceDebtorInInvoice, [glb.selectedDebtorUuid, [glb.otherDebtorUuids]]); + transaction.addQuery(replaceDebtorInPatient, [glb.selectedDebtorUuid, [glb.otherDebtorUuids]]); - transaction.addQuery(replacePatientInEmployee, [selectedUuid, otherUuids]); - transaction.addQuery(replacePatientInPatientAssignment, [selectedUuid, otherUuids]); - transaction.addQuery(replacePatientInPatientDocument, [selectedUuid, otherUuids]); - transaction.addQuery(replacePatientInPatientHospitalization, [selectedUuid, otherUuids]); - transaction.addQuery(replacePatientInPatientVisit, [selectedUuid, otherUuids]); + transaction.addQuery(replacePatientInEmployee, [selectedPatientUuid, [otherPatientUuids]]); + transaction.addQuery(replacePatientInPatientAssignment, [selectedPatientUuid, [otherPatientUuids]]); + transaction.addQuery(replacePatientInPatientDocument, [selectedPatientUuid, [otherPatientUuids]]); + transaction.addQuery(replacePatientInPatientHospitalization, [selectedPatientUuid, [otherPatientUuids]]); + transaction.addQuery(replacePatientInPatientVisit, [selectedPatientUuid, [otherPatientUuids]]); - transaction.addQuery(removeOtherPatients, [otherUuids]); + transaction.addQuery(removeOtherPatients, [otherPatientUuids]); transaction.addQuery(removeOtherDebtors, [glb.otherDebtorUuids]); return transaction.execute(); }) - .then(rows => { + .then(() => { res.sendStatus(204); }) .catch(next) - - res.sendStatus(200); + .done(); } diff --git a/test/end-to-end/patient/registry.merge.page.js b/test/end-to-end/patient/registry.merge.page.js new file mode 100644 index 0000000000..dcf46f990e --- /dev/null +++ b/test/end-to-end/patient/registry.merge.page.js @@ -0,0 +1,18 @@ +/* global element, by */ + +// const FU = require('../../shared/FormUtils'); +// const GU = require('../../shared/GridUtils'); + +function PatientMergePage() { + const page = this; + const gridId = 'patient-registry'; + + page.gridId = gridId; + + page.openMergeTool = async function openMergeTool() { + element(by.css('[data-action="open-tools"]')).click(); + element(by.css('[data-action="merge-patient"]')).click(); + }; +} + +module.exports = PatientMergePage; diff --git a/test/end-to-end/patient/registry.merge.spec.js b/test/end-to-end/patient/registry.merge.spec.js new file mode 100644 index 0000000000..98088a05ee --- /dev/null +++ b/test/end-to-end/patient/registry.merge.spec.js @@ -0,0 +1,11 @@ +const MergePatientPage = require('./registry.merge.page'); + +describe('Merge Patients', () => { + + const Page = new MergePatientPage(); + + it('successfully merge two selected patients into one', async () => { + await Page.openMergeTool(); + }); + +}); diff --git a/test/end-to-end/patient/registry.spec.js b/test/end-to-end/patient/registry.spec.js index 4aa12a2307..23ca11e16a 100644 --- a/test/end-to-end/patient/registry.spec.js +++ b/test/end-to-end/patient/registry.spec.js @@ -1,10 +1,14 @@ const helpers = require('../shared/helpers'); const PatientRegistrySearch = require('./registry.search'); +const PatientMerge = require('./registry.merge.spec'); // patient registry tests -describe('Patient Registry', () => { +describe.only('Patient Registry', () => { before(() => helpers.navigate('#/patients')); // groups patient search modal queries describe('Search', PatientRegistrySearch); + + // merge patients + describe('Merge patients', PatientMerge); }); diff --git a/test/integration/patients.js b/test/integration/patients.js index 4bfbc8dc14..7c93aacc93 100644 --- a/test/integration/patients.js +++ b/test/integration/patients.js @@ -2,56 +2,79 @@ const helpers = require('./helpers'); -describe('(/patients) Patients', () => { - // TODO Should this import UUID library and track mock patient throughout? - const mockPatientUuid = '85BF7A8516D94AE5B5C01FEC9748D2F9'; - const mockDebtorUuid = 'EC4241E43558493B9D78DBAA47E3CEFD'; - const missingPatientUuid = 'D74BC1673E14487EAF7822FD725E4AC1'; - - const mockDebtor = { - uuid : mockDebtorUuid, +// TODO Should this import UUID library and track mock patient throughout? +const mockPatientUuid = '85BF7A8516D94AE5B5C01FEC9748D2F9'; +const mockDebtorUuid = 'EC4241E43558493B9D78DBAA47E3CEFD'; +const missingPatientUuid = 'D74BC1673E14487EAF7822FD725E4AC1'; +const mockPatientDoublonUuid = 'WWBF7A8516D94AE5B5C01FEC9748D2F9'; +const mockDebtorDoublonUuid = 'WW4241E43558493B9D78DBAA47E3CEFD'; + +const mockDebtor = { + uuid : mockDebtorUuid, + debtor_group_uuid : '4DE0FE47177F4D30B95FCFF8166400B4', +}; + +const mockPatient = { + display_name : 'Mock Patient First', + dob : new Date('1993-06-01'), + current_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', + origin_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', + sex : 'M', + project_id : 1, + hospital_no : 120, + uuid : mockPatientUuid, +}; + +// missing last name, sex +const missingParamsPatient = { + display_name : 'Mock Patient', + dob : new Date('1993-06-01'), + current_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', + origin_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', + project_id : 1, + hospital_no : 121, + uuid : missingPatientUuid, +}; + +const mockRequest = { + finance : mockDebtor, + medical : mockPatient, +}; + +const mockMissingRequest = { + finance : { debtor_group_uuid : '4DE0FE47177F4D30B95FCFF8166400B4', - }; - - const mockPatient = { - display_name : 'Mock Patient First', - dob : new Date('1993-06-01'), - current_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', - origin_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', - sex : 'M', - project_id : 1, - hospital_no : 120, - uuid : mockPatientUuid, - }; - - // missing last name, sex - const missingParamsPatient = { - display_name : 'Mock Patient', - dob : new Date('1993-06-01'), - current_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', - origin_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', - project_id : 1, - hospital_no : 121, - uuid : missingPatientUuid, - }; - - const mockRequest = { - finance : mockDebtor, - medical : mockPatient, - }; - - const mockMissingRequest = { - finance : { - debtor_group_uuid : '4DE0FE47177F4D30B95FCFF8166400B4', - }, - medical : missingParamsPatient, - }; - - const badRequest = { - incorrectLayout : mockDebtor, - incorrectTest : mockPatient, - }; + }, + medical : missingParamsPatient, +}; + +const badRequest = { + incorrectLayout : mockDebtor, + incorrectTest : mockPatient, +}; + +const mockDebtorDoublon = { + uuid : mockDebtorDoublonUuid, + debtor_group_uuid : '4DE0FE47177F4D30B95FCFF8166400B4', +}; + +const mockPatientDoublon = { + display_name : 'Mock Patient First Doublon', + dob : new Date('2017-08-24'), + current_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', + origin_location_id : '1F162A109F6747889EFFC1FEA42FCC9B', + sex : 'M', + project_id : 1, + hospital_no : 220, + uuid : mockPatientDoublonUuid, +}; + +const mockDoublonRequest = { + finance : mockDebtorDoublon, + medical : mockPatientDoublon, +}; +describe('(/patients) Patients', () => { // HTTP API Test for /patients/ routes describe('Patient Search', () => { @@ -238,6 +261,9 @@ describe('(/patients) Patients', () => { .catch(helpers.handler); }); + // merge patients + describe('merge patients', MergePatients); + // hospital number uniqueness tests describe('/hospital_number/:id/exists', HospitalNumber); @@ -249,6 +275,42 @@ describe('(/patients) Patients', () => { describe('patient subsidies', subsidies); }); +// patients merge +function MergePatients() { + // add a doublon + it('POST /patients will register a valid doublon patient', () => { + return agent.post('/patients') + .send(mockDoublonRequest) + .then((res) => { + helpers.api.created(res); + }) + .catch(helpers.handler); + }); + + const params = { + selected : mockPatientUuid, + other : [mockPatientDoublonUuid], + }; + + it('POST /patients/merge will merge two patients into one', () => { + return agent.post('/patients/merge') + .send(params) + .then((res) => { + expect(res).to.have.status(204); + }) + .catch(helpers.handler); + }); + + it('GET /patients returns a correct reduced list of patients', () => { + const INITIAL_TEST_PATIENTS_PLUS_ONE_ADDED = 5; + return agent.get('/patients') + .then((res) => { + helpers.api.listed(res, INITIAL_TEST_PATIENTS_PLUS_ONE_ADDED - 1); + }) + .catch(helpers.handler); + }); +} + // Tests for /patients/:uuid/groups function PatientGroups() {