Skip to content

Add an event, notification(s), and task(s)

Patrick Bolger edited this page May 6, 2016 · 3 revisions

An event, as used here, represents an activity, associated with the use of PETS, that require special action - on particular, notifications of interested parties and/or creation of one or more tasks for follow-up activity.

The process of adding an event to PETS will be explained by using example code associated with a job application being submitted to a job - usually by a job seeker directly, although a job developer can submit an application on behalf of a job seeker.

Create the event

This event is created when a successful job application occurs.

Create the event at the point of occurrence

jobs_controller.rb contains this code:

begin
  @job.apply @job_seeker
  Event.create(:JS_APPLY, @job.last_application_by_job_seeker(@job_seeker))

which calls Event.create method upon successful application. Note that the JobApplication instance is passed to that method.

Add logic to Event.create

Add event type

Add the event to the EVT_TYPE hash:

EVT_TYPE = {JS_REGISTER:   'js_registered',
            COMP_REGISTER: 'company_registered',
            JS_APPLY:      'jobseeker_applied'}

Add logic for handling the event to the case statement:

when :JS_APPLY                          # evt_obj = job application
      # Business rules:
      #    Notify job seeker's case manager
      #    Notify job seeker's job developer
      #    Notify company contact associated with the job
      #    Create task for 'job application' (application to be reviewed)
      
      notify_list = notify_list_for_js_apply_event(evt_obj)

      unless notify_list.empty?
        Pusher.trigger('pusher_control',
                       EVT_TYPE[:JS_APPLY],
                       {job_id:  evt_obj.job.id,
                        js_id:   evt_obj.job_seeker.id,
                        js_name: evt_obj.job_seeker.full_name(last_name_first: false),
                        notify_list: notify_list[0]})

        NotifyEmailJob.set(wait: @@delay.seconds).
                       perform_later(notify_list[1],
                       EVT_TYPE[:JS_APPLY],
                       evt_obj)
      end

      Task.new_review_job_application_task(evt_obj.job, evt_obj.job.company)

The business rules associated with the event should be included as comments. In this case, we need to notify the job seeker's job developer (if exists), case manager (if exists) and the company person associated with the job (if exists). Here, "notify" means to send a realtime popup message to the user's browser (which they will see if logged in) and also send an email.

The Pusher.trigger method accepts three arguments. The first is specified as 'pusher_control', verbatim. That is the channel that clients (browser) subscribe to for listening for events. The second argument is the value (string) of the event that was added to EVT_TYPE. The third is a hash with values to be sent with the message via the channel (Pusher will convert this to a JSON structure). Here, we're including information regarding the application, as well as an array of User ID's who are to receive the notification in their browser.

Note that emails are sent asynchronously via DelayedJob, via the call to NotifyEmailJob (see app/jobs/notify_email_job.rb). DelayedJob will invoke an actual ActionMailer method after a prescribed delay. Note that in this case we are passing the JobApplication instance to the ActionMailer method. This allows us to use that object in the email template for specific data values to be included in the notification email. Additional information regarding configuring the email is not included in this document.

Lastly, we call Task create function (see below).

Configure Pusher

Add an event handler to the setup() function in pusher.js.erb. In particular, bind the event processing function to the Pusher channel used to listen for server-originated events. In this case, this looks like:

channel.bind('jobseeker_applied', function(data) {
      // Process event if I am logged in and I am in notify list
      if ($.inArray(parseInt(Cookies('user_id')), data.notify_list) != -1) {
        Notification.info_notification('Job Seeker: ' +
            "<a href='/job_seekers/" + data.js_id +
            " target='_blank'>" + data.js_name + "</a>" +
            " has applied to <a href='/jobs/" + data.job_id +
            "' target='_blank'>this job</a>");
      }
    });

Note that the first argument to channel.bind must be the value of specific EVT_TYPE in the Event class.

Here, we are determining if the user's "User" ID (added to cookies when user logs in to PETS) is included in the list of notification recipient ID's defined in Event.create. If a match, we create a popup message to the user.

Configure the task handler

To do this, add code to app/models/concerns/task_manager/business_logic/rb.

The comments at the beginning of that file adequately explain the process to be followed. For this example, the ':job_application' task type was added to these two constants:

DESCRIPTIONS = {:need_job_developer => 'Job Seeker has no assigned Job Developer',
                    :need_case_manager  => 'Job Seeker has no assigned Case Manager',
                    :company_registration => 'Review company registration',
                    :job_application => 'Review job application'}
    ASSIGNABLE_LIST = {:need_job_developer => {type: :agency, function: :job_developers},
                       :need_case_manager => {type: :agency, function: :case_managers},
                       :company_registration => {type: :agency, function: :agency_admins},
                       :job_application => {type: :company, function: :all}}

And this method was added to module ClassMethods:

def new_review_job_application_task job, company
        create_task({:company => {company: company, role: :CA}}, :job_application, job)
      end

NOTE: the third argument to create_task is the 'target' of the task - that is, the object for which action is to be taken. Note that this object can only be one of three types: Company, Person or Job. This is why the job is passed to the method rather than the actual job application.