module PsUtilities::PreBuiltPost

Public Instance Methods

create_student(params)
Alias for: create_students
create_students(params) click to toggle source

this method CREATES or INSERTS a new student into PowerSchool @param params (Array of Hashes) - kids with their attributes use format: one kid params: { students: [{dcid: 7531, student_id: 23456, email: “kid1@las.ch”}] }

or multiple students (with ps and your school's database extensions) params: { students:

[ { dcid: 9753, student_id: 65432 },
  { dcid: 7531, student_id: 23456, email: "kid@las.ch",
    u_studentsuserfields: {transcriptaddrcity: "Bex"},
    u_students_extension: {preferredname: "Joe"}
  }
]

} @return [Hash] { “results”: {

  "update_count": 2
  "result": [
    {  "client_uid": 124,
       "status": "SUCCESS",
       "action": "INSERT",
       "success_message" :{
         "id": 442,
         "ref": "https://server/ws/v1/student/442" }
     },
     { ... }
  ]
}

} @note create_students REQUIRED params are: :student_id (chosen by the school same as local_id within PS), :last_name, :first_name, :entry_date, :exit_date, :school_number, :grade_level @note create_students OPTIONAL params include: :school_id, :username, :middle_name, physical address objects, mailing address objects, demographics objects, contacts objects, schedule setup objects, intial enrollment objects (disctrict and school), :contact_info, :phone, :u_studentsuserfields (powerschool defined extensions) & :u_students_extension (school defined db extensions) @note create_students INVALID (ignored) params are: :id (dcid - chosen by the PS system)

# File lib/ps_utilities/pre_built_post.rb, line 37
def create_students(params)
  action   = "INSERT"
  kids_api_array = build_kids_api_array(action, params)
  options  = { body: { students: { student: kids_api_array } }.to_json }
  answer = api(:post, "/ws/v1/student", options)
  return answer.parsed_response   if answer.code.to_s.eql? "200"
  return {"errorMessage"=>"#{answer.response}"}
end
Also aliased as: create_student
update_student(params)
Alias for: update_students
update_students(params) click to toggle source

this updates and existing student record within PowerSchool (see create_students) @note update_students REQUIRED params are: :id (dcid) and :student_id (local_id) @note update_students INVALID (ignored) params are: :grade_level, :entry_date, :exit_date, :school_number, :school_id

# File lib/ps_utilities/pre_built_post.rb, line 51
def update_students(params)
  action = "UPDATE"
  kids_api_array = build_kids_api_array(action, params)
  return kids_api_array     if kids_api_array.empty?

  options  = { body: { students: { student: kids_api_array } }.to_json }
  answer = api(:post, "/ws/v1/student", options)
  return answer.parsed_response   if answer.code.to_s.eql? "200"
  return {"errorMessage"=>"#{answer.response}"}
end
Also aliased as: update_student

Private Instance Methods

build_kid_attributes(action, kid) click to toggle source

prepare an indivdual's attributes to be sent to PowerSchool @param action [String, “UPDATE” or “INSERT”] - handles what powerschool should do @param kid [Hash] - one kid's attributes within a hash @return [Hash] - returns data in the below format: Data structure to send to API (with built-in PS extensions) { :action=>“UPDATE”,

:id=>7337,
:client_uid=>"555807",
:contact_info=>{:email=>"bassjoe@las.ch"},
"_extension_data"=> {
  "_table_extension"=>  [
    { "recordFound"=>false,
      "name"=>"u_students_extension",
      "_field"=> [
        {"name"=>"preferredname", "type"=>"String", "value"=>"Joe"},
        {"name"=>"student_email", "type"=>"String", "value"=>"bassjoe@las.ch"}
      ]
    },
    { "recordFound"=>false,
      "name"=>"u_studentsuserfields",
      "_field"=> [
        {"name"=>"transcriptaddrline1", "type"=>"String", "value"=>"LAS"},
        {"name"=>"transcriptaddrline2", "type"=>"String", "value"=>"CP 108"},
        {"name"=>"transcriptaddrcity", "type"=>"String", "value"=>"Leysin"},
        {"name"=>"transcriptaddrzip", "type"=>"String", "value"=>"1854"},
        {"name"=>"transcriptaddrstate", "type"=>"String", "value"=>"Vaud"},
        {"name"=>"transcriptaddrcountry", "type"=>"String", "value"=>"CH"}
      ]
    }
  ]
}
# File lib/ps_utilities/pre_built_post.rb, line 186
def build_kid_attributes(action, kid)
  if kid.nil? or not kid.is_a?(Hash) or kid.empty?
    raise ArgumentError, "STUDENT format is: {students: [{kid_data1}, {kid_data2}]} - NOT OK: #{kid}"
  end
  if action.nil? or not action.is_a?(String) or action.empty? or not %[INSERT UPDATE].include?(action)
    raise ArgumentError, "ACTION must be: 'INSERT' or 'UPDATE' - NOT OK: #{action}"
  end
  # ALWAYS NEEDED INFO
  attribs                        = {action: action}
  attribs[:client_uid]           = kid[:student_id].to_s
  attribs[:student_username]     = kid[:username]        if kid[:username]

  # REQUIRED ON ENROLLMENT (optional later)
  attribs[:name]                 = {}
  case action
  when 'INSERT'
    # must be set on creation (INSERT)
    attribs[:local_id]           = kid[:local_id].to_i   if kid[:local_id]
    attribs[:local_id]           = kid[:student_id].to_i if kid[:student_id]
    # to create an account both first and last name must be present
    attribs[:name][:last_name]   = kid[:last_name]   if kid[:last_name] or kid[:first_name]
    attribs[:name][:first_name]  = kid[:first_name]  if kid[:last_name] or kid[:first_name]
    attribs[:name][:middle_name] = kid[:middle_name] if kid[:middle_name]
    # school_enrollment can only be SET on INSERT!
    attribs[:school_enrollment]  = {}
    if kid[:enroll_status_code]
      attribs[:school_enrollment][:enroll_status_code] = kid[:enroll_status_code]
    elsif kid[:status_code]
      attribs[:school_enrollment][:status_code]  = kid[:status_code]
    end
    attribs[:school_enrollment][:grade_level]    = kid[:grade_level]   if kid[:grade_level]
    attribs[:school_enrollment][:entry_date]     = kid[:entry_date]    if kid[:entry_date]
    attribs[:school_enrollment][:exit_date]      = kid[:exit_date]     if kid[:exit_date]
    attribs[:school_enrollment][:school_number]  = kid[:school_number] if kid[:school_number]
    attribs[:school_enrollment][:school_id]      = kid[:school_id]     if kid[:school_id]
  when 'UPDATE'
    # don't allow nil / blank name updates
    attribs[:id]                 = kid[:id] || kid[:dcid]
    attribs[:name][:last_name]   = kid[:last_name]   if kid[:last_name]
    attribs[:name][:first_name]  = kid[:first_name]  if kid[:first_name]
    attribs[:name][:middle_name] = kid[:middle_name] if kid[:middle_name]
  end

  # OPTIONAL FIELDS
  attribs[:address] = {}
  if kid[:physical_street] or kid[:physical_city] or kid[:physical_state_province] or
      kid[:physical_postal_code] or kid[:physical_grid_location]
    attribs[:address][:physical] = {}
    attribs[:address][:physical][:street] = kid[:physical_street]      if kid[:physical_street]
    attribs[:address][:physical][:city]   = kid[:physical_city]        if kid[:physical_city]
    attribs[:address][:physical][:state_province] = kid[:physical_state]    if kid[:physical_state]
    attribs[:address][:physical][:postal_code]    = kid[:physical_postal_code] if kid[:physical_postal_code]
    attribs[:address][:physical][:grid_location]  = kid[:physical_grid_location] if kid[:physical_grid_location]
  end
  if kid[:mailing_street] or kid[:mailing_city] or kid[:mailing_state_province] or
      kid[:mailing_postal_code] or kid[:mailing_grid_location]
    attribs[:address][:mailing] = {}
    attribs[:address][:mailing][:street] = kid[:mailing_street]      if kid[:mailing_street]
    attribs[:address][:mailing][:city]   = kid[:mailing_city]        if kid[:mailing_city]
    attribs[:address][:mailing][:state_province] = kid[:mailing_state]    if kid[:mailing_state]
    attribs[:address][:mailing][:postal_code]    = kid[:mailing_postal_code] if kid[:mailing_postal_code]
    attribs[:address][:mailing][:grid_location]  = kid[:mailing_grid_location] if kid[:mailing_grid_location]
  end
  attribs[:contact] = {}
  if kid[:emergency_phone1] && kid[:emergency_contact_name1]
    attribs[:contact][:emergency_phone1]        = kid[:emergency_phone1]
    attribs[:contact][:emergency_contact_name1] = kid[:emergency_contact_name1]
  end
  if kid[:emergency_phone2] && kid[:emergency_contact_name2]
    attribs[:contact][:emergency_phone2]        = kid[:emergency_phone2]
    attribs[:contact][:emergency_contact_name2] = kid[:emergency_contact_name2]
  end
  if kid[:doctor_phone] && kid[:doctor_name]
    attribs[:contact][:doctor_phone]  = kid[:doctor_phone]
    attribs[:contact][:doctor_name]   = kid[:doctor_name]
  end
  attribs[:contact][:guardian_email]  = kid[:guardian_email]   if kid[:guardian_email]
  attribs[:contact][:guardian_fax]    = kid[:guardian_fax]     if kid[:guardian_fax]
  attribs[:contact][:mother]          = kid[:mother]           if kid[:mother]
  attribs[:contact][:father]          = kid[:father]           if kid[:father]
  attribs[:contact] = nil            if attribs[:contact].empty?
  #
  attribs[:demographics] = {}
  attribs[:demographics][:gender]     = kid[:gender]           if kid[:gender]
  attribs[:demographics][:birth_date] = kid[:birth_date]       if kid[:birth_date]
  attribs[:demographics][:projected_graduation_year] = kid[:projected_graduation_year] if kid[:projected_graduation_year]
  attribs[:demographics][:ssn]        = kid[:ssn]              if kid[:ssn]
  #
  attribs[:schedule_setup] = {}
  attribs[:schedule_setup][:home_room]   = kid[:home_room]     if kid[:home_room]
  attribs[:schedule_setup][:next_school] = kid[:next_school]   if kid[:next_school]
  attribs[:schedule_setup][:sched_next_year_grade] = kid[:sched_next_year_grade] if kid[:sched_next_year_grade]
  #
  attribs[:initial_enrollment] = {}
  attribs[:initial_enrollment][:school_entry_date]          = kid[:school_entry_date]          if kid[:school_entry_date]
  attribs[:initial_enrollment][:school_entry_grade_level]   = kid[:school_entry_grade_level]   if kid[:school_entry_grade_level]
  attribs[:initial_enrollment][:district_entry_date]        = kid[:district_entry_date]        if kid[:district_entry_date]
  attribs[:initial_enrollment][:district_entry_grade_level] = kid[:district_entry_grade_level] if kid[:district_entry_grade_level]
  #
  attribs[:contact_info]     = {email: kid[:email]}                  if kid[:email]
  attribs[:phone]            = {main: {number: kid[:mobile]}}        if kid[:mobile]

  # Update LAS Database Extensions as needed
  attribs["_extension_data"] = { "_table_extension" => [] }
  # built-in extensions by PowerSchool
  attribs["_extension_data"]["_table_extension"] << u_studentsuserfields(kid[:u_studentsuserfields]) if kid[:u_studentsuserfields]
  # school defined database extensions
  attribs["_extension_data"]["_table_extension"] << u_students_extension(kid[:u_students_extension]) if kid[:u_students_extension]
  # if no extension data present make it empty
  attribs["_extension_data"] = {}                if attribs["_extension_data"]["_table_extension"].empty?

  # remove, nils, empty strings and empty hashes
  answer = attribs.reject { |k,v| v.nil? || v.to_s.empty? || v.to_s.eql?("{}")}
  # pp "kid-attributes"
  # pp answer
  return answer
end
build_kids_api_array(action, params) click to toggle source
@param action [String] - either "INSERT" or "UPDATE"
@param params [Array of Hashes] - in this format -- students: [{kid_1_info}, {kid_2_info}]
@return [Array of Hashes] - with data like below:

[ {:action=>“UPDATE”,

:id=>7337,
:client_uid=>"555807",
:contact_info=>{:email=>"bassjoe@las.ch"},
"_extension_data"=> {
  "_table_extension"=>  [
    { "recordFound"=>false,
      "name"=>"u_students_extension",
      "_field"=> [
        {"name"=>"preferredname", "type"=>"String", "value"=>"Joe"},
        {"name"=>"student_email", "type"=>"String", "value"=>"bassjoe@las.ch"}
      ]
    },
    { "recordFound"=>false,
      "name"=>"u_studentsuserfields",
      "_field"=> [
        {"name"=>"transcriptaddrline1", "type"=>"String", "value"=>"LAS"},
        {"name"=>"transcriptaddrline2", "type"=>"String", "value"=>"CP 108"},
        {"name"=>"transcriptaddrcity", "type"=>"String", "value"=>"Leysin"},
        {"name"=>"transcriptaddrzip", "type"=>"String", "value"=>"1854"},
        {"name"=>"transcriptaddrstate", "type"=>"String", "value"=>"Vaud"},
        {"name"=>"transcriptaddrcountry", "type"=>"String", "value"=>"CH"}
      ]
    }
  ]
}
{ ...another_student_data... },

]

@note this is then sent to the API call with a body tag
# File lib/ps_utilities/pre_built_post.rb, line 97
def build_kids_api_array(action, params)
  # ugly protection against bad data feeds - but it works
  # TODO: refactor with an elegant assertion?
  if params.nil? or not params.is_a?(Hash) or params[:students].nil? or not params[:students].is_a?(Array) or params[:students].empty? or not params[:students][0].is_a?(Hash)
    raise ArgumentError, "PARAMS format is: {students: [{kid_data1}, {kid_data2}]} - NOT OK: #{params}"
  end
  if action.nil? or not action.is_a?(String) or action.empty? or not %[INSERT UPDATE].include?(action)
    raise ArgumentError, "ACTION must be: 'INSERT' or 'UPDATE' - NOT OK: #{action}"
  end
  api_array = []
  students  =  params.dig(:students)
  students.each do |kid|
    api_array << build_kid_attributes(action, kid)
  end
  api_array
end
u_students_extension(data) click to toggle source

prepare data to update student database extensions @param data [Hash] - with the format: {u_students_extension: {field1: data1, field2: data2}} @return [Hash] - with data like below: { “name”=>“u_students_extension”,

"recordFound"=>false,
"_field"=> [
  {"name"=>"preferredname", "type"=>"String", "value"=>"Joe"},
  {"name"=>"student_email", "type"=>"String", "value"=>"joe@las.ch"},
]

}

# File lib/ps_utilities/pre_built_post.rb, line 124
def u_students_extension(data)
  db_extensions = { "name"=>"u_students_extension", "recordFound"=>false,
                    "_field"=> [] }
  data.each do |key, value|
    db_extensions["_field"] << {"name"=>"#{key}", "type"=>"String", "value"=>"#{value}"}
  end
  db_extensions
end
u_studentsuserfields(data) click to toggle source

prepare data to built-in database extensions @param data [Hash] - with the format: {u_studentsuserfields: {field1: data1, field2: data2}} @return [Hash] - with data like below: { “name”=>“u_students_extension”,

"recordFound"=>false,
"_field"=> [
  {"name"=>"transcriptaddrzip", "type"=>"String", "value"=>75230},
  {"name"=>"transcriptaddrcountry", "type"=>"String", "value"=>"United States"},
  {"name"=>"transcriptaddrcity", "type"=>"String", "value"=>"dallas"},
  {"name"=>"transcriptaddrstate", "type"=>"String", "value"=>"Texas"},
  {"name"=>"transcriptaddrline1", "type"=>"String", "value"=>"6138 meadow rd"}
]

}

# File lib/ps_utilities/pre_built_post.rb, line 146
def u_studentsuserfields(data)
  db_extensions = { "name"=>"u_studentsuserfields", "recordFound"=>false,
                    "_field"=> [] }
  data.each do |key, value|
    db_extensions["_field"] << {"name"=>"#{key}", "type"=>"String", "value"=>"#{value}"}
  end
  db_extensions
end