Skip to content

Commit

Permalink
Display fines using FOLIO model
Browse files Browse the repository at this point in the history
  • Loading branch information
marlo-longley committed Jul 18, 2023
1 parent 8c678c6 commit 5bbb790
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 77 deletions.
33 changes: 19 additions & 14 deletions app/models/folio/fine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ class Fine

attr_reader :record

# ? FOLIO: need to recalibrate these statuses
FINE_STATUS = {}.freeze

def initialize(record)
@record = record
end

def key
record['feeFineId']
record['id']
end

def sequence
Expand All @@ -32,25 +29,21 @@ def status
end

def nice_status
record['feeFineType']
record.dig('feeFine', 'feeFineType')
end

# returns the equivalent Symphony library code
def library
Folio::LocationsMap.for(record.dig('item', 'item', 'effectiveLocation', 'code'))&.first
record.dig('item', 'effectiveLocation', 'library', 'name')
end

def bill_date
if record['dateCreated'] || record.dig(
'metadata', 'createdDate'
)
Time.zone.parse(record['dateCreated'] || record.dig('metadata',
'createdDate'))
end
return if record['actions'].none?

Time.zone.parse(record.dig('actions', 0, 'dateAction'))
end

def owed
record['remaining']&.to_d || fee
record['remaining']&.to_d
end

def fee
Expand All @@ -61,6 +54,18 @@ def bib?
record['item'].present?
end

def author
record.dig('item', 'instance', 'contributors')&.pluck('name')&.join(', ')
end

def title
record.dig('item', 'instance', 'title')
end

def call_number
record.dig('item', 'holdingsRecord', 'callNumber')
end

def to_partial_path
'fines/fine'
end
Expand Down
57 changes: 25 additions & 32 deletions app/services/folio_graphql_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,46 +163,39 @@ def patron_info(patron_uuid)
patronComments
}
accounts {
item {
instance {
id
}
id
effectiveShelvingOrder
effectiveCallNumberComponents {
callNumber
}
permanentLocation {
name
}
}
id
userId
remaining
amount
dateCreated
feeFineId
feeFineType
feeFine {
id
automatic
feeFineType
defaultAmount
chargeNoticeId
actionNoticeId
ownerId
metadata {
createdDate
createdByUserId
createdByUsername
updatedDate
updatedByUserId
updatedByUsername
}
}
metadata {
createdDate
actions {
amountAction
balance
id
dateAction
}
paymentStatus {
name
}
item {
id
effectiveLocation {
library {
name
}
}
instance {
title
contributors {
name
}
}
holdingsRecord {
callNumber
}
}
}
loans {
id
Expand Down
4 changes: 3 additions & 1 deletion app/views/fines/_fine.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
<h3 class="clamp-3 record-title title text-reset"><%= fine.title if fine.bib? %></h3>
</div>
<div class="order-3 order-md-2 d-flex flex-row flex-grow-1 row col-md-3">
<div class="w-50 col-md-12 col-lg-6 clamp-1 author"><%= fine.author if fine.bib? %></div>
<div class="w-50 col-md-12 col-lg-6 clamp-1 author">
<%= fine.author if fine.bib? %>
</div>
<div class="w-50 col-md-12 col-lg-6 call_number" data-shelfkey="<%= fine.shelf_key if fine.bib? %>"><%= fine.call_number if fine.bib? %></div>
</div>
<button class="col-2 col-md order-2 order-md-3 btn collapsed stretched-link position-static" type="button" data-toggle="collapse" data-target="#collapseDetails-<%= fine.key.parameterize %>" aria-expanded="false" aria-controls="collapseDetails-<%= fine.key.parameterize %>">
Expand Down
77 changes: 77 additions & 0 deletions spec/models/folio/fine_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Folio::Fine do
subject(:fine) do
described_class.new(record.with_indifferent_access)
end

let(:record) do
{ 'id' => '4a00ff2c-8a03-4614-8430-e350e8195642',
'userId' => 'd7b67ab1-a3f2-45a9-87cc-d867bca8315f',
'remaining' => 15,
'amount' => 25,
'feeFine' => { 'feeFineType' => 'Manual Replacement Fee' },
'actions' =>
[{ 'amountAction' => 25,
'balance' => 25,
'id' => 'a0b8d6ae-c7c5-4bda-9405-076d8b21412f',
'dateAction' => '2023-07-18T00:06:51.538+00:00' },
{ 'amountAction' => 10,
'balance' => 15,
'id' => '86c03816-d7de-471e-a99d-90b3b9b4a5f8',
'dateAction' => '2023-07-18T00:07:19.517+00:00' }],
'paymentStatus' => { 'name' => 'Paid partially' },
'item' =>
{ 'effectiveLocation' => { 'library' => { 'name' => 'Art and Architecture' } },
'instance' => { 'title' => '"Star shining on the mountain',
'contributors' => [{ name: 'Author 1' }, { name: 'Author 2' }] },
'holdingsRecord' => { 'callNumber' => 'MD 7520' } } }
end

describe '#key' do
subject(:key) { fine.key }

it 'has a key' do
expect(key).to eq '4a00ff2c-8a03-4614-8430-e350e8195642'
end
end

describe '#author' do
subject(:author) { fine.author }

it 'returns the authors' do
expect(author).to eq 'Author 1, Author 2'
end
end

describe '#patron_key' do
subject(:patron_key) { fine.patron_key }

context 'when the fine is not a proxy fine' do
it { expect(patron_key).to eq 'd7b67ab1-a3f2-45a9-87cc-d867bca8315f' }
end

# TODO
# context 'when the fine is a proxy fine' do
# let(:record) do
# { 'details' =>
# { 'proxyUserId' => 'bdfa62a1-758c-4389-ae81-8ddb37860f9b',
# 'proxy' => { 'firstName' => 'Piper', 'lastName' => 'Proxy', 'barcode' => 'Proxy1' } } }
# end

# it { expect(fine.patron_key).to eq 'bdfa62a1-758c-4389-ae81-8ddb37860f9b' }
# end
end

context 'with a partially paid fine' do
it 'has a remaining balance' do
expect(fine.owed).to eq 15
end

it 'displays the full fee amount' do
expect(fine.fee).to eq 25
end
end
end
112 changes: 82 additions & 30 deletions spec/views/fines/index.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,100 @@
require 'rails_helper'

RSpec.describe 'fines/index' do
let(:fine) do
instance_double(Symphony::Fine, owed: 3, status: 'A', sequence: '1', nice_status: 'Damaged',
bib?: false, key: 'abc', bill_date: Date.new, fee: 5,
library: 'Best Lib', barcode: '12345')
end
let(:fines) { [fine] }
let(:checkouts) { [] }
let(:patron) do
instance_double(Symphony::Patron, barcode: '1', fines: fines, can_pay_fines?: true, requests: [],
checkouts: checkouts, remaining_checkouts: nil, barred?: false,
status: 'OK', group?: false)
end
context 'with a Symphony Fine' do
let(:fine) do
instance_double(Symphony::Fine, owed: 3, status: 'A', sequence: '1', nice_status: 'Damaged',
bib?: false, key: 'abc', bill_date: Date.new, fee: 5,
library: 'Best Lib', barcode: '12345')
end
let(:fines) { [fine] }
let(:checkouts) { [] }
let(:patron) do
instance_double(Symphony::Patron, barcode: '1', fines: fines, can_pay_fines?: true, requests: [],
checkouts: checkouts, remaining_checkouts: nil, barred?: false,
status: 'OK', group?: false)
end

before do
assign(:fines, fines)
assign(:checkouts, checkouts)
without_partial_double_verification do
allow(view).to receive(:patron_or_group).and_return(patron)
allow(view).to receive(:patron).and_return(patron)
allow(fine).to receive(:to_partial_path).and_return('fines/fine')
before do
assign(:fines, fines)
assign(:checkouts, checkouts)
without_partial_double_verification do
allow(view).to receive(:patron_or_group).and_return(patron)
allow(view).to receive(:patron).and_return(patron)
allow(fine).to receive(:to_partial_path).and_return('fines/fine')
end
end
end

context 'when the patron has fines' do
it 'shows the shared computer payment alert' do
render
context 'when the patron has fines' do
it 'shows the shared computer payment alert' do
render

expect(rendered).to have_text('Shared computer users: Due to computer security risks, you should not use a shared computer to make a fine payment.') # rubocop:disable Layout/LineLength
end
end

expect(rendered).to have_text('Shared computer users: Due to computer security risks, you should not use a shared computer to make a fine payment.') # rubocop:disable Layout/LineLength
context 'when the patron has no fines' do
let(:patron) do
# create a patron with empty array for fines
instance_double(Symphony::Patron, barcode: '1', fines: [], can_pay_fines?: true, requests: [], checkouts: [],
remaining_checkouts: nil, barred?: false, status: 'OK', group?: false)
end

it 'does not show the shared computer payment alert' do
render

expect(rendered).not_to have_text('Shared computer users: Due to computer security risks, you should not use a shared computer to make a fine payment.') # rubocop:disable Layout/LineLength
end
end
end

context 'when the patron has no fines' do
context 'with a FOLIO Fine' do
let(:fine) do
instance_double(Folio::Fine, owed: 3, status: 'A', sequence: '1', nice_status: 'Damaged',
bib?: true, key: 'abc', bill_date: Date.new, fee: 5,
library: 'Best Lib', barcode: '12345', author: 'Author 1', title: 'Title', shelf_key: 'AB 1234', call_number: 'AB 1234', catkey: '12345')
end
let(:fines) { [fine] }
let(:checkouts) do
[Folio::Checkout.new(
{ 'id' => '31d15973-acb6-4a12-92c7-5e2d5f2470ed',
'item' =>
{ 'title' =>
'Mental growth during the first three years' },
'overdue' => true,
'details' =>
{ 'feesAndFines' => { 'amountRemainingToPay' => 10 } } }
)]
end
let(:patron) do
# create a patron with empty array for fines
instance_double(Symphony::Patron, barcode: '1', fines: [], can_pay_fines?: true, requests: [], checkouts: [],
remaining_checkouts: nil, barred?: false, status: 'OK', group?: false)
instance_double(Folio::Patron, barcode: '1', fines: fines, can_pay_fines?: true, requests: [],
checkouts: checkouts, remaining_checkouts: nil, barred?: false,
status: 'OK', group?: false)
end

it 'does not show the shared computer payment alert' do
before do
assign(:fines, fines)
assign(:checkouts, checkouts)
without_partial_double_verification do
allow(view).to receive(:patron_or_group).and_return(patron)
allow(view).to receive(:patron).and_return(patron)
allow(fine).to receive(:to_partial_path).and_return('fines/fine')
allow(checkouts).to receive(:recalled?).and_return(false)
end
end

it 'show the fined item author' do
render

expect(rendered).not_to have_text('Shared computer users: Due to computer security risks, you should not use a shared computer to make a fine payment.') # rubocop:disable Layout/LineLength
expect(rendered).to have_text('Author 1')
end

context 'when the patron has accruing fines' do
it 'shows the accrued amount' do
render

expect(rendered).to have_text('Accruing: $10.00')
end
end
end
end

0 comments on commit 5bbb790

Please sign in to comment.