Last active
September 19, 2018 13:15
-
-
Save martink-io/7a594b89c4fa4348b84bb4e4fec7983b 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
module AdminCommand | |
module Jobs | |
class Assign < BaseCommand | |
include Concerns::Common::Collection | |
include Concerns::Common::WithUser | |
include Concerns::Jobs::GuardFilters | |
GUARD_ERROR = "Error: Job Is Already Filled" | |
LICENCE_ERROR ="Error: Guard Has Unmet Licence Requirements" | |
# TODO: Revisit guard_job creation and relations. | |
# TODO: Handle errors. | |
def call | |
guard_ids = params[:guard_ids].split(',') | |
params[:job] = job | |
params[:guard] = guard | |
ActiveRecord::Base.transaction do | |
if job.unfilled? && are_guard_licences_active? | |
job.assign! do | |
job.guard_jobs.each do |guard_job| | |
guard_id = guard_ids.pop | |
raise ActiveRecord::Rollback unless guard_id && guard_job.guard_id.blank? | |
guard_job.update!(guard_id: guard_id) | |
JobMailer.job_assigned_email(job, guard_job.user).deliver_later | |
end | |
end | |
else | |
job.assign_error = job.unfilled? ? LICENCE_ERROR : GUARD_ERROR | |
end | |
end | |
job | |
end | |
def job | |
@job ||= Job.find(params[:job_id]) | |
end | |
def guard | |
@guard ||= User.find(params[:guard_ids].split(',')).first | |
end | |
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
module Concerns | |
module Jobs | |
module GuardFilters | |
extend ActiveSupport::Concern | |
included do | |
def apply_filters(jobs) | |
jobs = licence_ids_query(jobs) | |
if jobs.present? | |
jobs = order_query(jobs) | |
jobs = within_distance_query(jobs) | |
jobs = state_query(jobs) | |
jobs = specific_date_query(jobs) | |
jobs = date_range_query(jobs) | |
jobs = free_text_query(jobs) | |
jobs.page(page) | |
.per_page(per_page) | |
.includes(:job_licences, :client, :guard_jobs, job_licences: :licence) | |
end | |
end | |
def apply_stats_filters(jobs) | |
jobs = state_query(jobs) | |
jobs = specific_date_query(jobs) | |
jobs = date_range_query(jobs) | |
end | |
def order_query(jobs) | |
return jobs unless params[:order] | |
jobs.order(params[:order]) | |
end | |
def within_distance_query(jobs) | |
return jobs if place.blank? || !is_uk_postcode? | |
jobs_in_range = Job.within(guard_profile.distance_to_travel, origin: place).select([:id]) | |
jobs.where(id: jobs_in_range).order(Job.distance_sql(place)) | |
end | |
def licence_ids_query(jobs) | |
licence_ids_param = params[:licence_ids] | |
return [] if params[:job_state] == 'unfilled' && licence_ids_param.blank? | |
return jobs unless licence_ids_param.present? | |
licence_ids = licence_ids_param.is_a?(Array) ? licence_ids_param : licence_ids_param.split(',') | |
job_ids_by_licence = licence_ids.map do |licence_id| | |
JobLicence.where(licence_id: licence_id).pluck(:job_id) | |
end | |
# matching_job_ids = job_ids_by_licence.each_with_object(job_ids_by_licence.first) do |job_ids, matched_ids| | |
# matched_ids &= job_ids | |
# end | |
uniq_job_ids = job_ids_by_licence.flatten.uniq | |
jobs.where(id: uniq_job_ids) | |
end | |
def state_query(jobs) | |
return jobs unless params[:job_state].present? | |
return jobs.by_state(Job::CANCELLED_STATES) if params[:job_state] == 'cancelled' | |
return jobs.by_state(params[:job_state].split(',')) unless params[:job_state] == 'cancelled' | |
end | |
def free_text_query(jobs) | |
return jobs unless params[:query].present? | |
jobs.by_client(params[:query]) | |
end | |
def specific_date_query(jobs) | |
return jobs unless params[:specific_date].present? | |
specific_date = Time.parse(params[:specific_date]) | |
jobs = jobs.starting_after(specific_date.beginning_of_day) | |
.starting_before(specific_date.end_of_day) | |
end | |
def date_range_query(jobs) | |
return jobs unless params[:from_date].present? && params[:to_date].present? | |
from_date = Time.parse(params[:from_date]) | |
to_date = Time.parse(params[:to_date]) | |
jobs = jobs.starting_after(from_date.beginning_of_day) | |
.ending_before(to_date.end_of_day) | |
end | |
def matching_guard_licence_ids(job) | |
return [] unless job.guards.any? | |
job_licence_ids = job.job_licences.pluck(:licence_id) | |
# TODO: Change to take into consideration multiple guards | |
job.guards.first.guard_licences.where(licence_id: job_licence_ids).pluck(:id) | |
end | |
private | |
def place | |
@place ||= params[:place] if params[:place].present? | |
end | |
def guard_profile | |
@guard_profile ||= params[:guard_profile] | |
end | |
def is_uk_postcode? | |
return false unless guard_profile.present? | |
UKPostcode.parse(guard_profile.postcode).full_valid? | |
end | |
def are_guard_licences_active? | |
guard_licences_ids.each do |guard_licence_id| | |
return false if licence_check(guard_licence_id).status != 'active' | |
end | |
guard_licences_ids.blank? ? false : true | |
end | |
# GuardLicences IDs for all selected guards to be assigned (admin actor) | |
# GuardLicences IDs for current guard to accept the job (guard actor) | |
def guard_licences_ids | |
return [] unless params[:guard].present? && params[:job].present? | |
job_licence_ids = params[:job].job_licences.pluck(:licence_id) | |
guard_licences = params[:guard].guard_licences.where('status_changed_at > ?', 24.hours.ago) | |
guard_licences.where(licence_id: job_licence_ids).pluck(:id) | |
end | |
def licence_check(guard_licence_id) | |
LicenceCommand::VerifyGuardLicence.call(guard_licence_id: guard_licence_id) | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment