import get from "lodash/get"
import Calendly from "api/v1/calendly/model"
import BaseController from "api/BaseController"
import CoachingModel from "./model"
import { prepQuery } from "./helpers"
/**
* Controller for the @namespace /coachings
*
* @class CoachingsController
* @extends {BaseController}
*/
class CoachingsController extends BaseController {
constructor() {
super()
this.index = this.index.bind(this)
this.show = this.show.bind(this)
this.create = this.create.bind(this)
this.update = this.update.bind(this)
this.delete = this.delete.bind(this)
}
/**
* GET / Fetches all coaching by user email address
*
* @param {int} emailAddress | Identifiers reference to the user instance
* @returns [{CoachingModel}]
* @memberof CoachingsController
*/
async index(req, res) {
const { success, unprocessableEntity } = this.codes
const { emailAddress } = req.query
if (!emailAddress) {
res.status(unprocessableEntity).send({
success: "false",
message: "emailAddress_is_required",
error: "ERROR: emailAddress is required in the request query",
})
}
const query = prepQuery(req.query)
const coaching = new CoachingModel()
const result = await coaching.find(query).catch((error) => {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_error",
error,
})
throw error
})
res.status(success).send({
success: "true",
message: "coachings_retrieved_successfully",
coachings: get(result, "rows", []),
})
}
/**
* GET /:id Fetch specific user exercise by id
*
* @param {int} id
* @returns {CoachingModel}
* @memberof CoachingsController
*/
async show(req, res) {
const { success, notFound, unprocessableEntity } = this.codes
const { id } = req.params
const coaching = new CoachingModel()
const result = await coaching.find({ id }).catch((error) => {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_error",
error,
})
throw error
})
coaching.set(get(result, "rows[0]"))
if (coaching.error) {
res.status(notFound).send({
success: "false",
message: "coaching_not_found",
error: coaching.error,
})
return
}
res.status(success).send({
success: "true",
message: "coaching_retrieved_successfully",
coaching: coaching.props,
})
}
/**
* POST / Create an instance of coaching from a Calendly event
*
* @param {object} payload | payload from the event_created endpoint in the Calendly API
* @returns {CoachingModel}
* @memberof CoachingsController
*/
async create(req, res) {
const { success, unprocessableEntity, conflict } = this.codes
const { event_type: eventType, event, invitee } = req.body?.payload || {}
const { uuid: eventId } = eventType
const { email: inviteeEmail } = invitee
const {
uuid: calendlyId,
location,
canceled,
canceler_name: cancelerName,
cancel_reason: cancelReason,
canceled_at: canceledAt,
start_time: startTime,
created_at: createdAt,
} = event
if (!Calendly.eventTypeExists(eventId)) {
res.status(unprocessableEntity).send({
success: "false",
message: "event_type_does_not_exists",
error: Calendly.error,
})
return
}
const coaching = new CoachingModel({
eventType: eventId,
inviteeEmail,
location,
canceled,
cancelerName,
cancelReason,
canceledAt: canceledAt ? new Date(canceledAt) : null,
startTime: startTime ? new Date(startTime) : null,
createdAt: createdAt ? new Date(createdAt) : null,
calendlyId,
})
const doesCoachingExists = await coaching.exists({ calendlyId })
if (doesCoachingExists) {
res.status(conflict).send({
success: "false",
message: "coaching_already_exists",
error: coaching.error,
})
return
}
if (coaching.error) {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_create_failed",
error: coaching.error,
})
return
}
const result = await coaching.create()
.catch((error) => {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_create_failed",
error,
})
throw error
})
const createCoaching = get(result, "rows[0]")
if (createCoaching) {
res.status(success).send({
success: "true",
message: "coaching_created_successfully",
coaching: createCoaching,
})
}
}
/**
* PUT / Update an instance of coaching
*
* @param {boolean} completed
* @param {int} progress
* @param {boolean} like
* @param {date} doneAt
* @param {date} lastVisit
* @returns {CoachingModel}
* @memberof CoachingsController
*/
async update(req, res) {
const { success, unprocessableEntity, notFound } = this.codes
const { id } = req.params
const { ...newProps } = req.body
const coaching = new CoachingModel()
const result = await coaching.find({ id }).catch((error) => {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_update_failed",
error,
})
throw error
})
if (coaching.error) {
res.status(notFound).send({
success: "false",
message: "coaching_not_found",
error: coaching.error,
})
return
}
const oldCoaching = get(result, "rows[0]")
coaching.set({ ...oldCoaching, ...newProps })
if (coaching.error) {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_update_failed",
error: coaching.error,
})
return
}
const updatedCoaching = await coaching.update().catch((error) => {
res.status(unprocessableEntity).send({
success: "false",
message: "user_update_failed",
error,
})
throw error
})
if (get(updatedCoaching, "rows[0]")) {
res.status(success).send({
success: "true",
message: "coaching_updated_successfully",
coaching: coaching.props,
})
}
}
/**
* DELETE / Delete an instance of coaching
*
* @param {int} id
* @returns {CoachingModel}
* @memberof CoachingsController
*/
async delete(req, res) {
const { success, unprocessableEntity, notFound } = this.codes
const { id } = req.params
const coaching = new CoachingModel()
const result = await coaching.find({ id }).catch((error) => {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_delete_failed",
error,
})
throw error
})
if (coaching.error) {
res.status(notFound).send({
success: "false",
message: "coaching_not_found",
error: coaching.error,
})
return
}
const data = get(result, "rows[0]")
coaching.set({ ...data })
if (coaching.error) {
res.status(unprocessableEntity).send({
success: "false",
message: "coaching_delete_failed",
error: coaching.error,
})
return
}
const deletedCoaching = await coaching.delete().catch((error) => {
res.status(unprocessableEntity).send({
success: "false",
message: "user_delete_failed",
error,
})
throw error
})
if (get(deletedCoaching, "rows[0]")) {
res.status(success).send({
success: "true",
message: "coaching_deleted_successfully",
coaching: coaching.props,
})
}
}
}
export default CoachingsController