Skip to content

Commit

Permalink
Merge pull request #295 from CodeForBaltimore/188
Browse files Browse the repository at this point in the history
Issue 188 - Return number of emails contacted
  • Loading branch information
blakenan-bellese authored Nov 25, 2020
2 parents 98924d4 + 454b84a commit 6ad4ae2
Show file tree
Hide file tree
Showing 6 changed files with 1,890 additions and 1,455 deletions.
58 changes: 56 additions & 2 deletions Bmore-Responsive.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@
"response": []
},
{
"name": "Contact Send",
"name": "Contact Send Bulk",
"event": [
{
"listen": "test",
Expand Down Expand Up @@ -620,6 +620,60 @@
},
"response": []
},
{
"name": "Contact Send Single",
"event": [
{
"listen": "test",
"script": {
"id": "b38d3eef-47f0-4f9e-a710-d82c4fef5492",
"exec": [
"//get the 36 character id of the new contact and save it to env variable",
"//this will allow deletion of this in the Delete transaction",
"pm.environment.set(\"newContactId\", pm.response.text().slice(0,36));",
"",
"//confirm that request returns a success code of 200",
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "token",
"type": "text",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/contact/send/{{modelType}}/{{id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"contact",
"send",
"{{modelType}}",
"{{id}}"
]
}
},
"response": []
},
{
"name": "Update Contact",
"event": [
Expand Down Expand Up @@ -1406,4 +1460,4 @@
}
],
"protocolProfileBehavior": {}
}
}
8 changes: 4 additions & 4 deletions src/email/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const sendMail = async (to, subject, html, text) => {
* Send a forgot password email.
* @param {string} userEmail email address of the user we're sending to
* @param {string} resetPasswordToken temporary token for the reset password link
*
*
* @returns {Boolean}
*/
const sendForgotPassword = async (userEmail, resetPasswordToken) => {
Expand All @@ -45,8 +45,8 @@ const sendForgotPassword = async (userEmail, resetPasswordToken) => {
await sendMail(
userEmail,
'Password Reset - Healthcare Roll Call',
nunjucks.render('forgot_password_html.njk', { emailResetLink }),
nunjucks.render('forgot_password_text.njk', { emailResetLink })
nunjucks.render('forgot_password_html.njk', {emailResetLink}),
nunjucks.render('forgot_password_text.njk', {emailResetLink})
)
return true
} catch (e) {
Expand Down Expand Up @@ -74,4 +74,4 @@ const sendContactCheckInEmail = async (info) => {
}
}

export default { sendForgotPassword, sendContactCheckInEmail }
export default {sendForgotPassword, sendContactCheckInEmail}
85 changes: 72 additions & 13 deletions src/routes/contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import email from '../email'
import models from '../models'
import utils from '../utils'
import validator from 'validator'
import { Router } from 'express'
import {Router} from 'express'

const router = new Router()
router.use(utils.authMiddleware)
Expand Down Expand Up @@ -33,7 +33,7 @@ router.get('/', async (req, res) => {
}
}

const contacts = await models.Contact.findAll({ where })
const contacts = await models.Contact.findAll({where})

// Temp fix for JSON types and Sequelize.
let results = []
Expand Down Expand Up @@ -103,7 +103,7 @@ router.post('/', async (req, res) => {
const response = new utils.Response()
try {
if (req.body.name !== undefined && req.body.name !== '') {
const { name, phone, email, UserId, entities, attributes } = req.body
const {name, phone, email, UserId, entities, attributes} = req.body

// Validating emails
if (email) {
Expand All @@ -115,7 +115,7 @@ router.post('/', async (req, res) => {
}
}

const contact = await models.Contact.create({ name, email, phone, UserId, attributes })
const contact = await models.Contact.create({name, email, phone, UserId, attributes})
let ec

if (entities) {
Expand Down Expand Up @@ -154,10 +154,10 @@ router.post('/send', async (req, res) => {
try {
/** @todo allow for passing entity and contact arrays */
const emails = []
const { entityIds, contactIds, relationshipTitle } = req.body
const {entityIds, contactIds, relationshipTitle} = req.body

if (entityIds === undefined && contactIds === undefined) {
const whereClause = (relationshipTitle !== undefined) ? { where: { relationshipTitle } } : {}
const whereClause = (relationshipTitle !== undefined) ? {where: {relationshipTitle}} : {}
const associations = await models.EntityContact.findAll(whereClause)

if (associations.length < 1) {
Expand Down Expand Up @@ -191,12 +191,71 @@ router.post('/send', async (req, res) => {
email.sendContactCheckInEmail(e)
})

response.setMessage('Contacts emailed')
response.setMessage({
results: {
message: 'Contacts emailed',
total: emails.length
}
})
} catch (e) {
console.error(e)
response.setCode(500)
}

return res.status(response.getCode()).send(response.getMessage())
})


router.post('/send/:type/:id', async (req, res) => {
const response = new utils.Response()

try {
let entity
if (req.params.type.toLowerCase() === 'entity') {
entity = await models.Entity.findById(req.params.id)
} else if (req.params.type.toLowerCase() === 'contact') {
entity = await models.Contact.findOne({
where: {
id: req.params.id
}
})
}

if (entity.email !== null) {
const primary = entity.email.filter(e => e.isPrimary === 'true').length ? entity.email.filter(e => e.isPrimary === 'true')[0] : entity.email[0]
// short-lived temporary token that only lasts one hour
const temporaryToken = await utils.getToken(req.params.id, primary.address, 'Entity')

const e = {
email: primary.address,
name: entity.name,
entityName: entity.name,
entityId: entity.id,
token: temporaryToken
}
email.sendContactCheckInEmail(e).then(() => {
response.setMessage(`${entity.name} emailed sent.`)
response.setCode(200)
}, err => {
response.setMessage('There was an error: ' + err)
response.setCode(500)
})
} else {
response.setMessage('Email Address not found.')
response.setCode(404)
}

response.setMessage({
results: {
message: `${entity.name} emailed.`,
}
})
} catch (e) {
console.error(e)
response.setCode(500)
}


return res.status(response.getCode()).send(response.getMessage())
})

Expand All @@ -205,7 +264,7 @@ router.put('/', async (req, res) => {
const response = new utils.Response()
try {
if (validator.isUUID(req.body.id)) {
const { id, name, phone, email, UserId, entities, attributes } = req.body
const {id, name, phone, email, UserId, entities, attributes} = req.body

const contact = await models.Contact.findOne({
where: {
Expand Down Expand Up @@ -299,7 +358,7 @@ router.post('/link/:contact_id', async (req, res) => {
}
})

let i=0
let i = 0
for (const entity of req.body.entities) {
const entityToLink = await models.Entity.findOne({
where: {
Expand All @@ -312,11 +371,11 @@ router.post('/link/:contact_id', async (req, res) => {
entityId: entityToLink.id,
contactId: contact.id,
}

if (entity.title) {
ec.relationshipTitle = contact.title
}

await models.EntityContact.createIfNew(ec)
i++
}
Expand Down Expand Up @@ -350,7 +409,7 @@ router.post('/unlink/:contact_id', async (req, res) => {
}
})

let i=0
let i = 0
for (const entity of req.body.entities) {
const entityToUnLink = await models.Entity.findOne({
where: {
Expand All @@ -366,7 +425,7 @@ router.post('/unlink/:contact_id', async (req, res) => {
contactId: contact.id
}
})

await ec.destroy()
i++
}
Expand Down
45 changes: 37 additions & 8 deletions src/routes/csv.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,65 @@
import { Router } from 'express'
import {Router} from 'express'
import utils from '../utils'
import { parseAsync } from 'json2csv'
import {parseAsync} from 'json2csv'
import {Op} from 'sequelize'

const router = new Router()
router.use(utils.authMiddleware)

// Gets a data dump from the passed in model (if it exists).
router.get('/:model_type', async (req, res) => {

const response = new utils.Response()
const modelType = req.params.model_type

try {

/** @todo refactor this when we change how CSV's are delivered. */
// eslint-disable-next-line no-prototype-builtins
if (req.context.models.hasOwnProperty(modelType) && modelType !== 'User' && modelType !== 'UserRole') {
/** @todo add filtering */
const results = await req.context.models[modelType].findAll({ raw: true })
let options = {raw: true}
// search by name if filter query param is included
if (req.query && req.query.filter && req.query.filter.length) {
options.where = {
name: {
[Op.iLike]: '%' + req.query.filter + '%'
}
}
}

const processedResults = await utils.processResults(results, modelType)
/** @todo add a search filter for status once data has a status field. */
let results = await req.context.models[modelType].findAll(options)

if (results.length !== 0) {
response.setMessage = await parseAsync(JSON.parse(JSON.stringify(processedResults)), Object.keys(results[0]), {})
const processedResults = await utils.processResults(results, modelType)
const fields = Object.keys(results[0])
parseAsync(processedResults, {fields}).then(csv => {
response.setMessage(csv)
const dateObj = new Date()
const dateStr = `${dateObj.getUTCMonth() + 1}_${dateObj.getUTCDate()}_${dateObj.getUTCFullYear()}`
res.setHeader('Content-disposition', `attachment; filename=HCRC_${modelType}_${dateStr}.csv`)
res.set('Content-Type', 'text/csv')
return res.status(response.getCode()).send(response.getMessage())
}, err => {
response.setCode(500)
response.setMessage('Not able to parse data: ' + err)
return res.status(response.getCode()).send(response.getMessage())
})
} else {
response.setCode(200)
response.setMessage('No results found')
return res.status(response.getCode()).send(response.getMessage())
}
} else {
response.setCode(400)
response.setMessage('Model type is invalid')
return res.status(response.getCode()).send(response.getMessage())
}
} catch (e) {
console.error(e)
response.setCode(500)
return res.status(response.getCode()).send(response.getMessage())
}

return res.status(response.getCode()).send(response.getMessage())
})

export default router
6 changes: 3 additions & 3 deletions src/tests/contact.routes.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ describe('Contact tests', function() {
.post('/contact/send')
.set('Accept', 'application/json')
.set('authorization', authHeader)
.expect('Content-Type', 'text/html; charset=utf-8')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(200)
.end((err, res) => {
if (err) return done(err)
expect(res.text).to.equal('Contacts emailed')
expect(res.body.results.message).to.equal('Contacts emailed')
done()
})
} catch(e) {
Expand Down Expand Up @@ -259,7 +259,7 @@ describe('Contact tests', function() {
.get('/csv/Contact')
.set('Accept', 'application/json')
.set('authorization', authHeader)
.expect('Content-Type', 'text/html; charset=utf-8')
.expect('Content-Type', 'text/csv; charset=utf-8')
.expect(200)
// eslint-disable-next-line no-unused-vars
.end((err, res) => {
Expand Down
Loading

0 comments on commit 6ad4ae2

Please sign in to comment.