Last active
January 17, 2017 14:38
-
-
Save anjanaraveendra/c8e7110a574ddb5e33d87a2c027b1a92 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#SurveyController Class | |
class Api::V1::SurveysController < Api::V1::BaseController | |
before_action :set_survey, only: [:show, :questions] | |
def index | |
# Api to get all current user schedules for the current time | |
@schedules = @account.schedules.includes(:survey, survey_version: :departments).joins(:survey) | |
.where(surveys: { status: 1 }, completed_at: nil).where(ignore: false) | |
.where('schedules.start_time <= :time AND schedules.buffer_time >= :time', time: Time.current) | |
.order('schedules.start_time asc') | |
end | |
def reminder | |
# Api to Remind for Survey Completion | |
@schedules = @account.schedules.includes(:survey, :survey_version).joins(:survey) | |
.where(surveys: { status: 1 }, completed_at: nil).where(ignore: false).where.not(survey_versions: { notify_time: 0 }) | |
.where(schedules: { notify_time: Time.current.beginning_of_day..Time.current.end_of_day }) | |
.order('schedules.notify_time asc') | |
end | |
def history | |
# Survey listing for a day and status | |
@schedules = @account.schedules.includes(:survey, :survey_version).where(ignore: false) | |
.where(completed_at: Time.current.beginning_of_day..Time.current.end_of_day) | |
end | |
def history_show | |
# Pick a survey from history to get survey details | |
schedule = Schedule.find(params[:id]) | |
@survey = schedule.survey | |
if !schedule.completed_at.nil? | |
@answers = schedule.answers.group_by(&:question_id) | |
else | |
render json: { code: 404, status: 'not_found', payload: {}, errors: ['Survey not found'] } | |
end | |
end | |
def survey_details | |
# Details and Listing of all schedules for the user | |
@schedule = Schedule.includes(:survey_version).find(params[:id]) | |
@questions = (@schedule.survey_version.questions.order('created_at ASC') + Incident.default_questions) unless @schedule.survey_version.disable_default_questions | |
@questions = @schedule.survey_version.questions.order('created_at ASC') if @schedule.survey_version.disable_default_questions | |
@staffs = @account.organization.accounts | |
@departments = @account.organization.departments | |
end | |
def departments | |
# Api to retrieve departments | |
render json: { departments: @account.organization.departments.pluck(:id, :name) } | |
end | |
private | |
def set_survey | |
@survey = Survey.find(params[:id]) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == Schema Information | |
# | |
# Table name: surveys | |
# | |
# id :integer not null, primary key | |
# status :integer | |
# account_id :integer | |
# drafted_at :datetime | |
# published_on :datetime | |
# unpublished_on :datetime | |
# suspended_on :datetime | |
# archived_on :datetime | |
# marked_as :integer | |
# version_id :integer | |
# created_at :datetime not null | |
# updated_at :datetime not null | |
# questions_count :integer default(0) | |
# organization_id :integer | |
# | |
# Indexes | |
# | |
# index_surveys_on_organization_id (organization_id) | |
# | |
# Foreign Keys | |
# | |
# fk_rails_2c8e32429d (organization_id => organizations.id) | |
# | |
class Survey < ActiveRecord::Base | |
has_many :email_notifications, as: :item | |
belongs_to :version, class_name: 'SurveyVersion', foreign_key: 'version_id' | |
belongs_to :department | |
belongs_to :account | |
belongs_to :organization | |
has_many :survey_versions, dependent: :destroy | |
has_many :completed_surveys, dependent: :destroy | |
has_many :schedules, dependent: :destroy | |
enum status: %w(draft published suspended archived) | |
accepts_nested_attributes_for :survey_versions | |
def publish! | |
update_attributes(status: 1, published_on: Time.current, suspended_on: nil, archived_on: nil) | |
version.update_attribute(:unpublished_at, nil) | |
version.schedule! | |
end | |
def suspend! | |
update_attributes(status: 2, suspended_on: Time.current) | |
version.update_attribute(:unpublished_at, Time.current) | |
version.remove_future_schedules! | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == Schema Information | |
# | |
# Table name: survey_versions | |
# | |
# id :integer not null, primary key | |
# name :string | |
# start_time :datetime | |
# end_time :datetime | |
# is_recurring :boolean | |
# every :integer | |
# interval :integer | |
# recurs_on :text default([]), is an Array | |
# end_after :integer | |
# recurring_end_date :datetime | |
# survey_id :integer | |
# created_at :datetime not null | |
# updated_at :datetime not null | |
# questions_count :integer default(0) | |
# unpublished_at :datetime | |
# disabled_at :datetime | |
# notify_time :integer default(0) | |
# buffer_time :integer default(0) | |
# timezone :string | |
# disable_default_questions :boolean default(FALSE) | |
# | |
class SurveyVersion < ActiveRecord::Base | |
after_save :update_current_version_id | |
belongs_to :survey | |
belongs_to :account | |
has_many :survey_version_accounts, dependent: :destroy | |
has_many :questions, dependent: :destroy | |
has_many :accounts, -> { distinct }, through: :survey_version_accounts | |
has_many :department_survey_versions, dependent: :destroy | |
has_many :departments, -> { distinct }, through: :department_survey_versions | |
has_many :questions | |
has_many :sections, dependent: :destroy | |
has_many :schedules, dependent: :destroy | |
enum every: %w(day week month year hour minute) | |
def self.notify | |
[['Do not notify', 0], ['15 minutes', 15], ['30 minutes', 30], ['45 minutes', 45], ['1 hour', 60]] | |
end | |
def self.buffer | |
[ | |
['No buffer', 0], ['15 minutes', 15], ['30 minutes', 30], ['45 minutes', 45], | |
['1 hour', 60], ['1 hour and 15 minutes', 75], ['1 hour and 30 minutes', 90], | |
['1 hour and 45 minutes', 105], ['2 hours', 120] | |
] | |
end | |
# validate :start_date_cant_be_today | |
validate :start_time_cant_be_past | |
validate :end_must_be_greater_than_start | |
validate :end_should_be_same_date_as_start | |
validates :end_after, numericality: true, allow_nil: true | |
# validate :validate_department_presence | |
validates_presence_of :name, :start_time, :end_time, message: 'required' | |
validate :validate_weekly | |
validate :recurring_end_date_than_end | |
validate :occurance_should_be_greater_than_one | |
def schedule! | |
survey.reload | |
ScheduleService.new(self).this_week.each do |schedule| | |
next if survey.published_on.nil? | |
accounts.each do |account| | |
Schedule.find_or_create_by(schedule.merge(survey_id: survey_id, survey_version_id: id, account_id: account.id)) | |
end | |
end | |
end | |
def remove_future_schedules! | |
schedules.where('start_time >= ?', Time.current.beginning_of_day) | |
.where(completed_at: nil).where(ignore: false) | |
.destroy_all | |
end | |
private | |
def validate_weekly | |
if week? && recurs_on.empty? | |
errors.add(:recurs, 'select atleast one weekday') | |
end | |
end | |
def start_time_cant_be_past | |
if !start_time.blank? && start_time.in_time_zone(timezone) < Time.current.in_time_zone(timezone) | |
errors[:start_time] = 'can\'t be past' | |
end | |
end | |
def start_date_cant_be_today | |
return if start_time.blank? | |
if start_time.in_time_zone(timezone).to_date <= Date.today | |
errors[:start_time] = 'should be greater than today' | |
end | |
end | |
def end_must_be_greater_than_start | |
return if start_time.blank? && end_time.blank? | |
if start_time.in_time_zone(timezone) >= end_time.in_time_zone(timezone) | |
errors[:end_time] = 'should be greater than start time' | |
end | |
end | |
def end_should_be_same_date_as_start | |
return if start_time.blank? || end_time.blank? || start_time.in_time_zone(timezone) >= end_time.in_time_zone(timezone) | |
unless start_time.in_time_zone(timezone).to_date == end_time.in_time_zone(timezone).to_date | |
errors[:end_time] = 'should be same day as start day' | |
end | |
end | |
def occurance_should_be_greater_than_one | |
if end_after.present? && end_after < 1 | |
errors.add(:end_after, 'should be greater than 0') | |
end | |
end | |
def recurring_end_date_than_end | |
return if start_time.blank? || end_time.blank? || recurring_end_date.blank? | |
if recurring_end_date.in_time_zone(timezone) <= end_time.in_time_zone(timezone) | |
errors.add(:recurring_end_date, 'should be greater than end time') | |
end | |
end | |
def update_current_version_id | |
survey.update_attribute(:version_id, id) | |
end | |
def validate_department_presence | |
errors.add(:department_ids, 'required') if departments.blank? | |
end | |
extend ActiveSupport::Concern | |
included do | |
amoeba do | |
include_association :questions | |
include_association :accounts | |
include_association :survey_version_accounts | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#TaskController Class | |
class Api::V1::TasksController < Api::V1::BaseController | |
def create | |
@task = @account.tasks.new(task_params) | |
authorize @task | |
#If there is a safety_issue, send out an email | |
if @task.save | |
if @task.task_type == 'safety_issue' | |
@leads = @task.department.department_leads + @organization.executives | |
@leads.each do |lead| | |
ApplicationMailer.safety_issue_email(lead).deliver_now | |
end | |
end | |
render json: { status: 200, message: 'Task was successfully created' } | |
else | |
# Task validation errors response if task object fails to create. | |
render json: { messages: @task.errors.full_messages, status: :unprocessable_entity } | |
end | |
end | |
def show | |
if params[:task_status_id].present? | |
# Task Status response | |
@task_status = @account.task_statuses.find(params[:task_status_id]) | |
else | |
# Task Object response | |
@task = @account.tasks.find(params[:id]) if params[:task_status_id].nil? | |
end | |
end | |
def created_tasks | |
# Listing of Tasks created by current user | |
@tasks = @account.tasks.includes(:task_statuses).order(updated_at: :desc) | |
.paginate(page: (params[:page] || 1), per_page: (params[:per_page] || 10)) | |
end | |
def assigned_tasks | |
# Listing of tasks assigned to current user | |
@tasks = @account.task_statuses.where(status: [0, 1]).order(updated_at: :desc) | |
.paginate(page: (params[:page] || 1), per_page: (params[:per_page] || 10)) | |
end | |
def open | |
# Api to change Task status to open | |
@task_status = @account.task_statuses.find(params[:task_status_id]) | |
authorize @task_status | |
if @task_status.open! | |
render json: { status: 200, message: 'Successfully opened' } | |
else | |
render json: { messages: @task_status.task.errors.full_messages, status: :unprocessable_entity } | |
end | |
end | |
def accept | |
# Api to change Task status to accept | |
@task_status = @account.task_statuses.find(params[:task_status_id]) | |
authorize @task_status | |
# Send emails to Department Leads & Executive after task accept | |
if @task_status.accept! | |
department_leads = @task_status.task.department.department_leads | |
department_leads.each do |department_lead| | |
ApplicationMailer.accept_task(department_lead, @task_status, @account).deliver_now | |
end | |
render json: { status: 200, message: 'Successfully acccepted' } | |
else | |
render json: { messages: @task_status.task.errors.full_messages, status: :unprocessable_entity } | |
end | |
end | |
def reassign | |
# Api to handle task re-assignment | |
@task_status = @account.task_statuses.find(params[:task_status_id]) | |
authorize @task_status # Check current user role, allow only if role is Department-Lead/ Executive | |
if @task_status.task.reassign!(params[:assigned_to]) | |
render json: { status: 200, message: 'Successfully reassigned the task status' } | |
else | |
render json: { messages: @task_status.task.errors.full_messages, status: :unprocessable_entity } | |
end | |
end | |
def complete | |
# Api to change task status to complete | |
@task_status = @account.task_statuses.find(params[:task_status_id]) | |
authorize @task_status # Check current user role, allow only if role is Department-Lead/ Executive | |
if @task_status.close! | |
render json: { status: 200, message: 'Successfully completed' } | |
else | |
render json: { messages: @task_status.task.errors.full_messages, status: :unprocessable_entity } | |
end | |
end | |
def departments | |
# Listing all departments from current user's organization | |
@departments = @account.organization.departments | |
render json: { departments: @departments } | |
end | |
def department_users | |
# Get all users from selected departments(params[:ids]) | |
ids = JSON.parse(params[:ids]) # ids parsing handled from backend | |
@accounts = Account.includes(:departments).where(departments: { id: ids }).to_a | |
@accounts.delete(@account) | |
render json: { accounts: @accounts } | |
end | |
def user_departments | |
# Listing all departments where current user is part of | |
@user_departments = @account.departments | |
render json: { user_departments: @user_departments } | |
end | |
def update | |
# Task PATCH Api | |
@task = Task.find(params[:id]) | |
authorize @task | |
if @task.update(task_update_params) | |
render json: { status: 201, message: 'Your task was successfully updated' } | |
else | |
render json: { messages: @task.error.full_messages, status: 'unprocessable_entity' } | |
end | |
end | |
def destroy | |
# Deleting of a task | |
@task = Task.find(params[:id]) | |
authorize @task | |
if @task.destroy | |
render json: { status: 204, message: 'Task was deleted successfully' } | |
else | |
render json: { messages: @task.error.full_messages, status: 'Task could not be deleted' } | |
end | |
end | |
private | |
def pundit_user | |
# Setting @account with role checks | |
@account | |
end | |
def task_params | |
task_statuses = [] | |
if @account.type == 'User::User' | |
department_leads = Department.find(params[:task][:department_id]).department_leads | |
department_leads.each { |ac| task_statuses << { account_id: ac.id, created_by: @account.id } } | |
else | |
params[:task][:assigned_to].each { |ac| task_statuses << { account_id: ac, created_by: @account.id } } | |
end | |
# Params beautify | |
params[:task][:task_statuses_attributes] = task_statuses | |
params[:task][:organization_id] = @account.organization_id | |
params[:task][:task_type] = params[:task][:type] if params[:task][:type].present? | |
params.require(:task).permit(:name, :description, :department_id, :question_id, :organization_id, :end_time, :category, :task_type, task_list: [], task_statuses_attributes: [:account_id, :created_by]) | |
end | |
def task_update_params | |
# Update Task Beautify params | |
params[:task][:task_statuses_attributes].each { |ts| ts[:created_by] = @account.id } | |
params.require(:task).permit(:id, :name, :description, :department_id, :question_id, :category, :end_time, :task_type, task_list: [], task_statuses_attributes: [:id, :account_id, :created_by, :_destroy]) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == Schema Information | |
# | |
# Table name: tasks | |
# | |
# id :integer not null, primary key | |
# name :string | |
# description :text | |
# department_id :integer | |
# account_id :integer | |
# question_id :integer | |
# organization_id :integer | |
# task_list :text default([]), is an Array | |
# created_at :datetime not null | |
# updated_at :datetime not null | |
# task_type :integer default(0) | |
# end_time :datetime | |
# category :integer | |
# | |
# Indices | |
# | |
# index_tasks_on_account_id (account_id) | |
# index_tasks_on_department_id (department_id) | |
# index_tasks_on_organization_id (organization_id) | |
# index_tasks_on_question_id (question_id) | |
# | |
# Foreign Keys | |
# | |
# fk_rails_9d303107ad (question_id => questions.id) | |
# fk_rails_a0db1d9e05 (department_id => departments.id) | |
# fk_rails_c8d7e9affa (account_id => accounts.id) | |
# | |
# fk_rails_46f8d59d15 (question_id => questions.id) | |
# fk_rails_64f216c611 (account_id => accounts.id) | |
# fk_rails_792c09d6bc (department_id => departments.id) | |
# | |
class Task < ActiveRecord::Base | |
belongs_to :question | |
belongs_to :account | |
belongs_to :department | |
belongs_to :organization | |
has_many :task_statuses, dependent: :destroy | |
accepts_nested_attributes_for :task_statuses, allow_destroy: true | |
enum task_type: %w(normal process_improvement safety_issue) | |
# enum category: %w(accident surgery emergency po mm rm infec_control enviro_serv med_rec lab imaging adm med_surg ob icu o) | |
enum category: %w(financial_and_growth quality_and_safety people_and_service) | |
validates :name, :description, presence: true | |
# validates :task_list, presence: true, unless: Proc.new { |task| task.process_improvement? } | |
def reassign!(assign_to) | |
existing_ids = task_statuses.pluck(:account_id) | |
# Add new users | |
(assign_to - existing_ids).each do |u| | |
task_statuses.create(account_id: u) | |
end | |
# Remove old users | |
(existing_ids - assign_to).each do |u| | |
task_statuses.find_by_account_id(u).destroy | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment