-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic CRUD operations for the proxy user feature.
- Loading branch information
Showing
16 changed files
with
323 additions
and
7 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
class Account::ProxyUsersController < Account::ApplicationController | ||
|
||
before_action -> { add_breadcrumb t("account.proxy_users.breadcrumb.index"), account_proxy_users_path } | ||
before_action -> { add_breadcrumb t("account.proxy_users.breadcrumb.new"), new_account_proxy_user_path }, only: [:new, :create] | ||
before_action -> { add_breadcrumb t("account.proxy_users.breadcrumb.edit"), edit_account_proxy_user_path }, only: [:edit, :update] | ||
|
||
def index | ||
@proxy_users = current_user.proxy_users | ||
end | ||
|
||
def new | ||
if params[:barcode].present? | ||
ils_user = Ils.get_user(params[:barcode]) | ||
|
||
unless ils_user | ||
flash[:error] = t(".lookup.no_user_found_error", barcode: params[:barcode]) | ||
redirect_to new_account_proxy_user_path and return | ||
end | ||
|
||
ensure_proxy_is_not_self(ils_user.id) or return | ||
ensure_proxy_is_unique(ils_user.id) or return | ||
|
||
@proxy_user = current_user.proxy_users.build( | ||
ils_primary_id: ils_user.id, | ||
name: ils_user.full_name | ||
) | ||
else | ||
@proxy_user = current_user.proxy_users.build | ||
end | ||
end | ||
|
||
def create | ||
ProxyUser.transaction do | ||
@proxy_user = current_user.proxy_users.build(proxy_user_params) | ||
|
||
ensure_proxy_is_not_self(@proxy_user.ils_primary_id) or return | ||
ensure_proxy_is_unique(@proxy_user.ils_primary_id) or return | ||
|
||
if @proxy_user.save | ||
if create_proxy_user_in_alma(@proxy_user) | ||
flash[:success] = t(".success") | ||
redirect_to account_proxy_users_path | ||
else | ||
flash[:error] = t(".error") | ||
redirect_to account_proxy_users_path | ||
raise ActiveRecord::Rollback | ||
end | ||
else | ||
render :new, status: :unprocessable_entity | ||
end | ||
end | ||
end | ||
|
||
def edit | ||
@proxy_user = current_user.proxy_users.find(params[:id]) | ||
end | ||
|
||
def update | ||
@proxy_user = current_user.proxy_users.find(params[:id]) | ||
|
||
if @proxy_user.update(proxy_user_params) | ||
flash[:success] = t(".success") | ||
redirect_to account_proxy_users_path | ||
else | ||
render :edit, status: :unprocessable_entity | ||
end | ||
end | ||
|
||
def destroy | ||
ProxyUser.transaction do | ||
@proxy_user = current_user.proxy_users.find(params[:id]) | ||
|
||
if @proxy_user.destroy | ||
if delete_proxy_user_in_alma(@proxy_user) | ||
flash[:success] = t(".success") | ||
redirect_to account_proxy_users_path | ||
else | ||
flash[:error] = t(".error") | ||
redirect_to account_proxy_users_path | ||
raise ActiveRecord::Rollback | ||
end | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def proxy_user_params | ||
params.require(:proxy_user).permit(:ils_primary_id, :name, :note, :expired_at) | ||
end | ||
|
||
def create_proxy_user_in_alma(proxy_user) | ||
user_id = proxy_user.ils_primary_id | ||
user_details = get_user_details_from_alma(user_id) | ||
return false unless user_details | ||
|
||
# Get the existing proxies, or initialize an empty array | ||
# in case there are no proxies yet | ||
proxies = user_details["proxy_for_user"] ||= [] | ||
|
||
# Check if the proxy user already exists in Alma. This can happen if the | ||
# proxy user was created in Alma directly | ||
return true if proxies.any? { |p| p["primary_id"].downcase == current_user.ils_primary_id.downcase } | ||
|
||
# Add the proxy user for the current user | ||
proxies << { | ||
primary_id: current_user.ils_primary_id | ||
} | ||
user_details["proxy_for_user"] = proxies | ||
|
||
# Update the user in Alma | ||
update_user_details_in_alma(user_id, user_details) | ||
end | ||
|
||
def delete_proxy_user_in_alma(proxy_user) | ||
user_id = proxy_user.ils_primary_id | ||
user_details = get_user_details_from_alma(user_id) | ||
return false unless user_details | ||
|
||
# Get the existing proxies, or initialize an empty array | ||
# in case there are no proxies yet | ||
proxies = user_details["proxy_for_user"] ||= [] | ||
|
||
# Check if the proxy user exists in Alma. This can happen if the | ||
# proxy user was deleted in Alma directly | ||
return true if proxies.none? { |p| p["primary_id"].downcase == current_user.ils_primary_id.downcase } | ||
|
||
# Remove the proxy user for the current user | ||
user_details["proxy_for_user"] = proxies.reject do |p| | ||
p["primary_id"].downcase == current_user.ils_primary_id.downcase | ||
end | ||
|
||
# Update the user in Alma | ||
update_user_details_in_alma(user_id, user_details) | ||
end | ||
|
||
# Note: We use the Alma API directly in #get_user_details_from_alma and | ||
# #update_user_details_in_alma, rather than the Ils adapter. This | ||
# creates a direct dependecy on the Alma API. This is not ideal, but the | ||
# the proxy user feature is an Alma specific feature anyway, so we skip the | ||
# abstraction for now. | ||
|
||
def get_user_details_from_alma(user_id) | ||
Ils.adapter.api.get("users/#{user_id}") | ||
rescue AlmaApi::Error | ||
nil | ||
end | ||
|
||
def update_user_details_in_alma(user_id, user_details) | ||
Ils.adapter.api.put("users/#{user_id}", body: user_details.to_json) | ||
true | ||
rescue AlmaApi::Error => e | ||
Rails.logger.error(["Error updating user in Alma [#{e.code}]: #{e.message}", *e.backtrace].join($/)) | ||
false | ||
end | ||
|
||
def ensure_proxy_is_not_self(user_id) | ||
if user_id&.downcase == current_user.ils_primary_id.downcase | ||
flash[:error] = t(".cannot_proxy_self_error") | ||
redirect_to new_account_proxy_user_path and return | ||
end | ||
|
||
true | ||
end | ||
|
||
def ensure_proxy_is_unique(user_id) | ||
if current_user.proxy_users.exists?(ils_primary_id: user_id) | ||
flash[:error] = t(".already_exists_error", barcode: user_id) | ||
redirect_to new_account_proxy_user_path and return | ||
end | ||
|
||
true | ||
end | ||
|
||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
class ProxyUser < ApplicationUser | ||
class ProxyUser < ApplicationRecord | ||
|
||
belongs_to :user | ||
|
||
validates :ils_primary_id, presence: true | ||
validates :label, presence: true | ||
validates :ils_primary_id, presence: true, uniqueness: {scope: :user_id} # rubocop:disable Rails/UniqueValidationWithoutIndex | ||
validates :name, presence: true | ||
|
||
# Not stored in the database, but used to lookup the proxy user in the ILS | ||
attribute :barcode, :string | ||
|
||
end |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
= simple_form_for [:account, @proxy_user] do |f| | ||
= f.hidden_field :ils_primary_id | ||
= f.input :name, input_html: { readonly: true } | ||
= f.input :note | ||
= f.input :expired_at, as: :date, html5: true, start_year: Date.today.year, prompt: true | ||
= f.button :submit, t("save"), class: "btn btn-primary" | ||
= link_to t("cancel"), account_proxy_users_path, class: "btn btn-link" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
li.list-group-item.d-flex.justify-content-between.align-items-center | ||
.fw-bold | ||
= proxy_user.name | ||
= " (#{proxy_user.ils_primary_id})" | ||
|
||
- if proxy_user.expired_at.present? | ||
span.badge.bg-info.ms-2 = t(".expired_at", date: l(proxy_user.expired_at)) | ||
|
||
- if proxy_user.note.present? | ||
em: .text_muted = proxy_user.note | ||
div | ||
= link_to edit_account_proxy_user_path(proxy_user), class: "btn btn-primary btn-sm me-2" do | ||
i.fa-solid.fa-edit.fa-fw | ||
= link_to account_proxy_user_path(proxy_user), class: "btn btn-danger btn-sm", \ | ||
data: { turbo_method: :delete, turbo_confirm: t(".confirm_delete") } do | ||
i.fa-solid.fa-trash.fa-fw |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.card.card-shadowed | ||
.card-header | ||
h5.m-0 = t(".header") | ||
.card-body | ||
= render "alerts" | ||
= render "form" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
.card.card-shadowed | ||
.card-header.d-flex.align-items-center | ||
h5.m-0 | ||
=> t(".header") | ||
.ms-auto = link_to new_account_proxy_user_path, class: "btn btn-primary" do | ||
i.fa-solid.fa-plus.fa-fw.me-1 | ||
= t(".new_proxy_user") | ||
.card-body | ||
.callout.callout-info | ||
i.fa-solid.fa-info-circle.fa-fw.fa-lg.me-1 | ||
= t(".info") | ||
|
||
- if @proxy_users.present? | ||
ol.list-group | ||
= render partial: "proxy_user", collection: @proxy_users | ||
- else | ||
.alert.alert-info.mb-0.text-center | ||
= t(".no_proxy_users") |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
- if @proxy_user.ils_primary_id.blank? | ||
/ Lookup Form | ||
.card.card-shadowed | ||
.card-header | ||
h5.m-0 = t(".lookup.header") | ||
.card-body | ||
= render "alerts" | ||
|
||
= form_tag new_account_proxy_user_path, method: :get do | ||
.input-group | ||
span.input-group-text | ||
i.fa-solid.fa-id-card | ||
=< text_field_tag :barcode, params[:barcode], placeholder: t(".lookup.form.barcode_placeholder"), \ | ||
class: "form-control", autofocus: true, autocomplete: "off" | ||
= submit_tag t(".lookup.form.submit"), class: "btn btn-primary" | ||
= link_to t("cancel"), account_proxy_users_path, class: "btn btn-outline-primary" | ||
- else | ||
/ New Form | ||
.card.card-shadowed | ||
.card-header | ||
h5.m-0 = t(".header") | ||
.card-body | ||
= render "alerts" | ||
= render "form" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ de: | |
profile: Meine Daten | ||
loans_history: Ausleihhistorie | ||
pin: "PIN verwalten" | ||
proxy_users: "Proxy-Users" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
de: | ||
account: | ||
proxy_users: | ||
already_exists_error: "Es existiert bereits ein Proxy-User mit der Bibliotheksausweisnummer '%{barcode}'." | ||
cannot_proxy_self_error: "Sie können sich nicht selbst als Proxy-User einrichten." | ||
|
||
proxy_user: | ||
expired_at: "Gültig bis %{date}" | ||
confirm_delete: "Möchten Sie diesen Proxy-User wirklich löschen?" | ||
|
||
breadcrumb: | ||
index: "Proxy-Users" | ||
new: "Neuer Proxy-User" | ||
edit: "Proxy-User bearbeiten" | ||
|
||
index: | ||
header: "Proxy-Users" | ||
new_proxy_user: "Neuer Proxy-User" | ||
info: > | ||
Sie können hier andere Nutzer berechtigen, in Ihrem Namen bzw. auf Ihr Konto Medien auszuleihen. | ||
no_proxy_users: "Sie haben noch keine Proxy-User eingerichtet." | ||
|
||
new: | ||
header: "Neuer Proxy-User" | ||
lookup: | ||
header: "Nutzer suchen" | ||
form: | ||
submit: "Suchen" | ||
barcode_placeholder: "Bibliotheksausweisnummer" | ||
no_user_found_error: "Kein Nutzer mit der Bibliotheksausweisnummer '%{barcode}' gefunden." | ||
|
||
create: | ||
error: "Proxy-User konnte nicht eingerichtet werden. Es ist ein Fehler aufgetreten." | ||
success: "Proxy-User wurde erfolgreich eingerichtet." | ||
|
||
edit: | ||
header: "Proxy-User bearbeiten" | ||
|
||
update: | ||
success: "Proxy-User wurde erfolgreich aktualisiert." | ||
|
||
destroy: | ||
error: "Proxy-User konnte nicht gelöscht werden. Es ist ein Fehler aufgetreten." | ||
success: "Proxy-User wurde erfolgreich gelöscht." |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ en: | |
profile: My Account | ||
loans_history: Lending History | ||
pin: Manage PIN | ||
proxy_users: "Proxy-User" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,3 +63,4 @@ en: | |
This file contains 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
This file contains 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
Oops, something went wrong.