Skip to content

Commit

Permalink
Merge pull request #748 from puzzle/feature/745-fetch-people-search-e…
Browse files Browse the repository at this point in the history
…ntries-from-ptime

feature/745 fetch people search entries from ptime
  • Loading branch information
kcinay055679 authored Jul 29, 2024
2 parents 480e328 + 57ad58a commit 5411381
Show file tree
Hide file tree
Showing 30 changed files with 545 additions and 514 deletions.
8 changes: 0 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ GEM
crass (1.0.6)
cssbundling-rails (1.4.0)
railties (>= 6.0.0)
daemons (1.4.1)
database_cleaner (2.0.2)
database_cleaner-active_record (>= 2, < 3)
database_cleaner-active_record (2.1.0)
Expand All @@ -134,11 +133,6 @@ GEM
database_cleaner-core (2.0.1)
date (3.3.4)
deep_merge (1.2.2)
delayed_job (4.1.11)
activesupport (>= 3.0, < 8.0)
delayed_job_active_record (4.1.8)
activerecord (>= 3.0, < 8.0)
delayed_job (>= 3.0, < 5)
devise (4.9.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
Expand Down Expand Up @@ -484,9 +478,7 @@ DEPENDENCIES
config
countries
cssbundling-rails
daemons
database_cleaner
delayed_job_active_record
devise
dotenv
faker
Expand Down
14 changes: 7 additions & 7 deletions app/domain/ptime/assign_employee_ids.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@ def map_employees(should_map)
mapped_people_count = 0

@ptime_employees.each do |ptime_employee|
ptime_employee_firstname = ptime_employee['attributes']['firstname']
ptime_employee_lastname = ptime_employee['attributes']['lastname']
ptime_employee_firstname = ptime_employee[:attributes][:firstname]
ptime_employee_lastname = ptime_employee[:attributes][:lastname]
ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}"
ptime_employee_email = ptime_employee['attributes']['email']
ptime_employee_email = ptime_employee[:attributes][:email]
matched_skills_people = Person.where(ptime_employee_id: nil)
.where(name: ptime_employee_name)
.where(email: ptime_employee_email)

if matched_skills_people.empty?
unmatched_entries << { name: ptime_employee_name, id: ptime_employee['id'] }
unmatched_entries << { name: ptime_employee_name, id: ptime_employee[:id] }
elsif matched_skills_people.one?
if should_map
matched_skills_person = matched_skills_people.first
matched_skills_person.ptime_employee_id = ptime_employee['id']
matched_skills_person.ptime_employee_id = ptime_employee[:id]
matched_skills_person.save!
end
mapped_people_count += 1
else
ambiguous_entries << { name: ptime_employee_name, id: ptime_employee['id'] }
ambiguous_entries << { name: ptime_employee_name, id: ptime_employee[:id] }
end
end

Expand All @@ -60,7 +60,7 @@ def map_employees(should_map)

def fetch_data
puts 'Fetching required data...'
@ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data']
@ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })
@skills_people = Person.all
puts 'Successfully fetched data'
end
Expand Down
49 changes: 26 additions & 23 deletions app/domain/ptime/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,41 @@ def initialize
@base_url = "#{ENV.fetch('PTIME_BASE_URL')}/api/v1/"
end

def get(endpoint, params = {})
request(:get, @base_url + endpoint, params)
def request(method, endpoint, params = {})
path = @base_url + endpoint

if last_ptime_error_more_than_5_minutes_ago?
send_request_and_parse_response(method, path, params)
else
raise CustomExceptions::PTimeClientError, 'Error'
end
end

private

def request(method, path, params = nil)
path = "#{path}?#{URI.encode_www_form(params)}"
response = RestClient.send(method, path, headers)
JSON.parse(response.body)
rescue RestClient::BadRequest => e
msg = response_error_message(e)
e.message = msg if msg.present?
raise e
end
def last_ptime_error_more_than_5_minutes_ago?
last_request_time = ENV.fetch('LAST_PTIME_ERROR', nil)
return true if last_request_time.nil?

def response_error_message(exception)
JSON.parse(exception.response.body).dig('error', 'message')
rescue JSON::ParserError # rescue only JSON parsing errors
nil
last_request_time.to_datetime <= 5.minutes.ago
end

def headers
{
authorization: "Basic #{basic_token}",
content_type: :json,
accept: :json
}
def ptime_request(method, url)
RestClient::Request.new(
:method => method,
:url => url,
:user => ENV.fetch('PTIME_API_USERNAME'),
:password => ENV.fetch('PTIME_API_PASSWORD'),
:headers => { :accept => :json, :content_type => :json }
)
end

def basic_token
Base64.encode64("#{ENV.fetch('PTIME_API_USERNAME')}:#{ENV.fetch('PTIME_API_PASSWORD')}")
def send_request_and_parse_response(method, url, params)
url += "?#{params.to_query}" if method == :get && params.present?
response = ptime_request(method, url).execute
JSON.parse(response.body, symbolize_names: true)[:data]
rescue RestClient::ExceptionWithResponse
raise CustomExceptions::PTimeClientError, 'Error'
end
end
end
12 changes: 6 additions & 6 deletions app/domain/ptime/update_people_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ class UpdatePeopleData

# rubocop:disable Metrics
def run
ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data']
ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })
ptime_employees.each do |ptime_employee|
ptime_employee_firstname = ptime_employee['attributes']['firstname']
ptime_employee_lastname = ptime_employee['attributes']['lastname']
ptime_employee_firstname = ptime_employee[:attributes][:firstname]
ptime_employee_lastname = ptime_employee[:attributes][:lastname]
ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}"

skills_person = Person.find_by(ptime_employee_id: ptime_employee['id'])
skills_person = Person.find_by(ptime_employee_id: ptime_employee[:id])
skills_person ||= Person.new

skills_person.name = ptime_employee_name
skills_person.ptime_employee_id ||= ptime_employee['id']
ptime_employee['attributes'].each do |key, value|
skills_person.ptime_employee_id ||= ptime_employee[:id]
ptime_employee[:attributes].each do |key, value|
if key.to_sym.in?(ATTRIBUTE_MAPPING.keys)
skills_person[ATTRIBUTE_MAPPING[key.to_sym]] = value
end
Expand Down
5 changes: 5 additions & 0 deletions app/exceptions/custom_exceptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module CustomExceptions

class PTimeClientError < StandardError; end

end
4 changes: 4 additions & 0 deletions app/helpers/auth_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ def find_person_by_auth_user
def devise?
AuthConfig.keycloak? || Rails.env.test?
end

def ptime_available?
ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true))
end
end
33 changes: 33 additions & 0 deletions app/helpers/person_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,37 @@ def not_rated_default_skills(person)
certificate: false, core_competence: false })
end
end

def sorted_people
fetch_ptime_or_skills_data.sort_by { |e| e.first.downcase }
end

def fetch_ptime_or_skills_data
all_skills_people = Person.all.map { |p| [p.name, person_path(p)] }
return all_skills_people unless ptime_available?

ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })
build_dropdown_data(ptime_employees)
rescue CustomExceptions::PTimeClientError
ENV['LAST_PTIME_ERROR'] = DateTime.current.to_s
all_skills_people
end

def build_dropdown_data(ptime_employees)
ptime_employees.map do |ptime_employee|
ptime_employee_name = append_ptime_employee_name(ptime_employee)
skills_person = Person.find_by(ptime_employee_id: ptime_employee[:id])
ptime_employee_id = ptime_employee[:id]
already_exists = ptime_employee_id.in?(Person.pluck(:ptime_employee_id))
path = new_person_path(ptime_employee_id: ptime_employee_id)
path = person_path(skills_person) if already_exists

[ptime_employee_name, path]
end
end

# Once https://github.com/puzzle/skills/issues/744 is merged there should be no need for this
def append_ptime_employee_name(ptime_employee)
"#{ptime_employee[:attributes][:firstname]} #{ptime_employee[:attributes][:lastname]}"
end
end
4 changes: 2 additions & 2 deletions app/helpers/select_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

module SelectHelper
def select_when_availabale(obj)
selected = obj ? obj.id : ''
prompt = obj ? false : true
selected = obj.present? ? polymorphic_path(obj) : ''
prompt = obj.nil?
{ selected: selected, prompt: prompt, disabled: '' }
end

Expand Down
2 changes: 1 addition & 1 deletion app/javascript/controllers/dropdown_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export default class extends Controller {
}

handleChange(event) {
window.location.href = event.target.dataset.value + event.target.value;
window.location.href = event.target.value;
}
}
2 changes: 1 addition & 1 deletion app/views/people/_search.html.haml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
%div.d-flex.align-items-center.justify-content-between
%div.d-flex.col-9.gap-3
%span.col-6{"data-controller": "dropdown"}
= collection_select :person_id, :person, Person.all.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}}
= select :person_id, :person, options_for_select(sorted_people, select_when_availabale(person)), {prompt: person.nil?}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange"}}
%div.d-flex.align-items-center.text-gray
= "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at
%a.d-flex.justify-content-between#new-person-button{href: "/people/new"}
Expand Down
5 changes: 0 additions & 5 deletions bin/delayed_job

This file was deleted.

2 changes: 0 additions & 2 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,5 @@ class Application < Rails::Application

config.assets.enabled = true
config.assets.paths << Rails.root.join("uploads")

config.active_job.queue_adapter = :delayed_job
end
end
22 changes: 0 additions & 22 deletions db/migrate/20240701085558_create_delayed_jobs.rb

This file was deleted.

17 changes: 1 addition & 16 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_07_01_085558) do
ActiveRecord::Schema[7.0].define(version: 2024_06_24_122411) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -77,21 +77,6 @@
t.datetime "updated_at", precision: nil, null: false
end

create_table "delayed_jobs", force: :cascade do |t|
t.integer "priority", default: 0, null: false
t.integer "attempts", default: 0, null: false
t.text "handler", null: false
t.text "last_error"
t.datetime "run_at"
t.datetime "locked_at"
t.datetime "failed_at"
t.string "locked_by"
t.string "queue"
t.datetime "created_at"
t.datetime "updated_at"
t.index ["priority", "run_at"], name: "delayed_jobs_priority"
end

create_table "departments", force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at", null: false
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ services:
/bin/bash -c "
curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &&
apt-get install -y nodejs &&
npm install -g yarn && bin/assets &&
npm install -g yarn && yarn add nodemon esbuild && bin/assets &&
sleep infinity"
volumes:
- ./:/myapp
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"autoprefixer": "^10.4.17",
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.11.3",
"esbuild": "^0.20.0",
"nodemon": "^3.0.3",
"esbuild": "^0.23.0",
"nodemon": "^3.1.4",
"postcss": "^8.4.33",
"postcss-cli": "^11.0.0",
"sass": "^1.70.0",
Expand Down
Loading

0 comments on commit 5411381

Please sign in to comment.