-
-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(#8204): Add feature to support adding phone number when registering patients #8369
Conversation
…o include new person with phone number
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one. A couple of changes requested...
…patient creation based upon valid/invalid phone in addPatient trigger
Update: Also added logic where rather checking for phone_number field to have phone number value it checks for phone_number type filed in form to have phone_number value so people can do like : Field @tatilepizs This (point b) is why the invalid phone validation was still creating a Patient because we weren't hard exiting addPatient when that validation failed, unlike uniquePhone validation which would hard exit patient creation. Thanks for catching that. 👍 @dianabarsan Thanks for you help and please kindly review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really cool stuff. Thanks for implementing all the changes. I have some comments but mostly about readability and maintainability.
Awesome work!
api/src/services/report/smsparser.js
Outdated
const formattedAndValidatedPhone = phoneNumberParser.normalize(config.getAll(), raw); | ||
if (formattedAndValidatedPhone) { | ||
return formattedAndValidatedPhone; | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need an else here, because the previous if statement has a return.
@@ -461,6 +479,7 @@ const addPatient = (options) => { | |||
const doc = options.doc; | |||
const patientShortcode = options.doc.patient_id; | |||
const patientNameField = getPatientNameField(options.params); | |||
const patientPhoneField = getPatientPhoneField(config.getAll(), doc.form); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this function needs to get all the configs as the parameter.
contactTypeUtils.isPlace.args[0].should.deep.equal([{}, {_id: 'person', patient_id: '56987', type: 'person' }]); | ||
contactTypeUtils.isPlace.args[0].should.deep.equal( | ||
[{}, { _id: 'person', patient_id: '56987', type: 'person' }] | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add unit tests to cover this new functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting there should be no change here. Think its formatting changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was failing the 120 line eslint length check on this test hence Formatted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just picked this line to add the comment. I was referring to adding unit tests in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added tests for registration add_patient flow as well as function to get phone field.
@@ -248,6 +248,61 @@ describe('validations', () => { | |||
}); | |||
}); | |||
|
|||
it('unique phone validation should fail if db query for phone returns doc', () => { | |||
clock = sinon.useFakeTimers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are fake timers needed here? Same question for the test below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed. Thanks.
}) | ||
.then(() => utils.getDocs(docIds)) | ||
.then(updated => { | ||
console.log(updated); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this debug log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
chai.expect(updated[0].fields.phone_number).to.equal(patient_phone); | ||
chai.expect(updated[0].patient_id).to.not.be.null; | ||
}) | ||
.then(patients => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
patients will always be undefined here, because the previous block does not return anything. I think the block is missing this call:
return getContactsByReference([newPatientId, 'venus']);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added get patient call and asserted taht its undefined when phone is invalid.
.then(infos => { | ||
infos.forEach(info => { | ||
chai.expect(info).to.deep.nested.not.include({ 'transitions.registration.ok': false }); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also check that no patient_id field is added to the main doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Co-authored-by: Diana Barsan <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool stuff! I spotted some stuff and I'm still missing unit tests updates for the registration transition.
return; | ||
} | ||
|
||
if (formDef && formDef.fields) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can further simplify this like:
if (formDef && formDef.fields) { | |
if (!formDef?.fields) { | |
return; | |
} | |
return Object | |
.keys(formDef.fields) | |
.find(key => formDef.fields[key].type === 'phone_number'); | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
P.S. eslintrc for shared-libs was in 2018 which coudln't recognize the optional chaining syntax (?.) so upgraded it to 2020. 3 or 4 folders are already in 2020.
@@ -505,6 +525,14 @@ const addPatient = (options) => { | |||
patient.date_of_birth = doc.birth_date; | |||
} | |||
|
|||
if (patientPhoneField && doc.fields[patientPhoneField]) { | |||
if (!phoneNumberParser.validate(config.getAll(), (doc.fields[patientPhoneField]))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make this whole block more readable, please store doc.fields[patientPhoneField]
in a variable.
if (!phoneNumberParser.validate(config.getAll(), (doc.fields[patientPhoneField]))) { | |
const patientPhone = doc.fields[patientPhoneField]; | |
if (!phoneNumberParser.validate(config.getAll(), patientPhone)) { | |
.... | |
return; | |
} | |
patient.phone = patientPhone; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
contactTypeUtils.isPlace.args[0].should.deep.equal([{}, {_id: 'person', patient_id: '56987', type: 'person' }]); | ||
contactTypeUtils.isPlace.args[0].should.deep.equal( | ||
[{}, { _id: 'person', patient_id: '56987', type: 'person' }] | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just picked this line to add the comment. I was referring to adding unit tests in general.
|
||
return utils | ||
.updateSettings(testForm.forms.NP, 'sentinel') | ||
.then(utils.saveDocs(docs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to pass a function to the then
.then(utils.saveDocs(docs)) | |
.then()) => utils.saveDocs(docs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
return utils | ||
.updateSettings(testForm.forms.NP, 'sentinel') | ||
.then(utils.saveDocs(docs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.then(utils.saveDocs(docs)) | |
.then(() => utils.saveDocs(docs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
let newPatientId; | ||
return utils | ||
.updateSettings(testForm.forms.NP, 'sentinel') | ||
.then(utils.saveDocs(docs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.then(utils.saveDocs(docs)) | |
.then(() => utils.saveDocs(docs)) |
@@ -98,6 +98,150 @@ describe('registration', () => { | |||
after(() => utils.revertDb([], true)); | |||
afterEach(() => utils.revertDb(getIds(contacts), true)); | |||
|
|||
it('should add valid phone to patient doc', () => { | |||
const patient_phone = '+9779841123123'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use camelCase for variables.
const patient_phone = '+9779841123123'; | |
const patientPhone = '+9779841123123'; |
const patient_phone = '+97796666'; | ||
const patient_id =uuid(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use camelCase for variables.
const patient_phone = '+97796666'; | |
const patient_id =uuid(); | |
const patientPhone = '+97796666'; | |
const patientId = uuid(); |
return getContactsByReference([newPatientId, 'venus']); | ||
}) | ||
.then(patients => { | ||
chai.expect(patients[0]).to.be.undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I look at the test above, it seems that this should be returning an object with a rows
property instead of an array.
chai.expect(patients[0]).to.be.undefined; | |
chai.expect(patients.rows.length).to.equal(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done thanks.
}) | ||
.then(() => utils.getDocs(docIds)) | ||
.then(updated => { | ||
chai.expect(updated.patient_id).to.be.undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that updated
will be an array here.
chai.expect(updated.patient_id).to.be.undefined; | |
chai.expect(updated[0].patient_id).to.be.undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed thanks.
Doc update for the phone_number field here. Also closed PR for add_phone_number trigger as that functionality is done in add_patient. Updated description to reflect the same. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff @PrjShrestha !
transitionUtils.addRejectionMessage(doc, options.registrationConfig, 'provided_phone_not_valid'); | ||
return; | ||
} | ||
patient.phone = doc.fields[patientPhoneField]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
patient.phone = doc.fields[patientPhoneField]; | |
patient.phone = patientPhone; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
phone_number: (raw) => { | ||
const formattedAndValidatedPhone = phoneNumberParser.normalize(config.getAll(), raw); | ||
if (formattedAndValidatedPhone) { | ||
return formattedAndValidatedPhone; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PrjShrestha , would you mind adding Nepali digit supporting code for this type as well? Here's the sample PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Feature (#8204): Support adding phone number when registering patients via SMS
Description
This code aims to complete the following:
Users should be able to add a patient's phone number while registering a patient.
CHT should automatically append the default country code to the phone number before saving it to the database.
Sample Message:
[x] Added unit tests
[x] Tested locally by setting up cht
[x] Fixed eslint issues
[x] Doc update for new field phone_number
[x] [Doc update validation] (medic/cht-docs#1144)