Module: LoansHelper

Defined in:
app/helpers/loans_helper.rb

Instance Method Summary collapse

Instance Method Details

#arrayed_loan_year_hash(start_year, end_year) ⇒ Object



190
191
192
193
194
195
196
197
198
# File 'app/helpers/loans_helper.rb', line 190

def arrayed_loan_year_hash(start_year, end_year)
  return {} if start_year.blank? || end_year.blank?
  years = {}
  (start_year..end_year).to_a.each do |y|
    years[y] = []
  end
  years[nil] = []
  years
end

#keywords_on_loanable_itemsObject



105
106
107
# File 'app/helpers/loans_helper.rb', line 105

def keywords_on_loanable_items
  Keyword.joins(:tags).where(project_id: sessions_current_project_id).where(tags: {tag_object_type: ['Container', 'Otu', 'CollectionObject']}).distinct.all
end

#label_for_loan(loan) ⇒ Object



13
14
15
16
# File 'app/helpers/loans_helper.rb', line 13

def label_for_loan(loan)
  s = "loan #{loan.id}"
  s << loan.identifiers&.pluck(:cached)&.join(', ')
end

#loan_autocomplete_tag(loan) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
# File 'app/helpers/loans_helper.rb', line 24

def loan_autocomplete_tag(loan)
  return nil if loan.nil?
  [
    (:span, (identifier_tag(loan_identifier(loan)) || loan.id), class: [:feedback, 'feedback-thin', 'feedback-primary']),
    loan.loan_recipients.collect{|a| a.name}.join(', '),
    loan.recipient_email,
    loan.date_sent,
    loan.recipient_address,
    loan_status_tag(loan)
  ].delete_if{|b| b.blank? }.join(' - ').gsub(/\n/, '; ').html_safe
end

#loan_due_back_tag(loan) ⇒ Object



99
100
101
102
103
# File 'app/helpers/loans_helper.rb', line 99

def loan_due_back_tag(loan)
  'Due back on ' +
    ( loan.date_return_expected.present? ? loan.date_return_expected.to_s : 'NOT PROVIDED' ) +
    '.'
end

#loan_fulfillment_latency(loans) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'app/helpers/loans_helper.rb', line 168

def loan_fulfillment_latency(loans)
  s,e = loans_start_end_year(loans, :date_requested)
  d = arrayed_loan_year_hash(s,e)

  loans.where.not(date_requested: nil).where.not(date_sent: nil).all.pluck(:date_requested, :date_sent).each do |req, sent|
    y = req.year
    d[y].push(sent.jd - req.jd)
  end

  data = {}

  d.each do |y, times|
    if times.any?
      data[y] = (times.sum.to_f / times.length.to_f).to_i
    else
      data[y] = nil
    end
  end

  data
end

#loan_identifier(loan) ⇒ Object



36
37
38
# File 'app/helpers/loans_helper.rb', line 36

def loan_identifier(loan)
  loan.identifiers.where(type: 'Identifier::Local::LoanCode').first
end

#loan_items_totals_per_year(loans) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'app/helpers/loans_helper.rb', line 140

def loan_items_totals_per_year(loans)
  s,e = loans_start_end_year(loans, :date_sent)
  y = zeroed_loan_year_hash(s,e)
  data = [
    {name: 'Otus',
     data: y
    },
    {name: 'CollectionObjects',
     data: y.dup
    }
  ]

  q = selected_loan_items(loans)

  q.where(loan_item_object_type: 'Otu').joins(:loan).pluck(:date_sent, :total).each do |d, t|
    data.first[:data][d&.year] += t if t
  end

  q.where(loan_item_object_type: 'CollectionObject')
    .joins(:loan)
    .joins('JOIN collection_objects on collection_objects.id = loan_items.loan_item_object_id')
    .pluck(:date_sent, 'collection_objects.total' ).each do |d, t|
      data.last[:data][d&.year] += t if t
    end

  data
end


50
51
52
53
# File 'app/helpers/loans_helper.rb', line 50

def loan_link(loan)
  return nil if loan.nil?
  link_to(loan_tag(loan).html_safe, loan)
end

#loan_overdue_tag(loan) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/helpers/loans_helper.rb', line 86

def loan_overdue_tag(loan)
  if loan.date_return_expected.present?
    if loan.overdue?
      "#{loan.days_overdue} days overdue."
    else
      "#{loan.days_until_due} days until due."
    end
  else
    (:span, 'Due date NOT PROVIDED.', data: {icon: :warning})
  end

end

#loan_recipients_tag(loan) ⇒ Object



18
19
20
21
22
# File 'app/helpers/loans_helper.rb', line 18

def loan_recipients_tag(loan)
  return nil if loan.nil?
  recipients = loan.loan_recipients.collect{|lr| person_tag(lr)}.join.html_safe
  (recipients.presence || 'No recipients defined!')
end

#loan_status_tag(loan) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'app/helpers/loans_helper.rb', line 40

def loan_status_tag(loan)
  return nil if loan.nil?
  return tag.span('Returned/canceled', class: [:feedback, 'feedback-thin', 'feedback-success']) if loan.date_closed.present?
  if loan.date_return_expected.present?
    return tag.span("Due in #{distance_of_time_in_words_to_now(loan.date_return_expected)}", class: [:feedback, 'feedback-thin', 'feedback-information']) if loan.date_return_expected > Time.now
    return tag.span("#{distance_of_time_in_words(Time.now, loan.date_return_expected)} overdue", class: [:feedback, 'feedback-thin', 'feedback-danger']) if loan.date_return_expected < Time.now
  end
  return tag.span('Lost/destroyed', class: [:feedback, 'feedback-thin', 'feedback-warning']) if loan.loan_items.count == loan.loan_items.where(disposition: ['Lost', 'Destroyed']).distinct.count
end

#loan_tag(loan) ⇒ Object



3
4
5
6
7
8
9
10
11
# File 'app/helpers/loans_helper.rb', line 3

def loan_tag(loan)
  return nil if loan.nil?
  [
    (:span, (identifier_tag(loan_identifier(loan)) || loan.id), class: [:feedback, 'feedback-thin', 'feedback-primary']),
    loan.loan_recipients.collect{|a| a.name}.join(', '),
    loan.recipient_email,
    loan.date_sent,
    loan.recipient_address].delete_if{|b| b.blank? }.join(' - ').gsub(/\n/, '; ').html_safe
end

#loan_total_individuals(loan) ⇒ Object



269
270
271
272
273
274
275
# File 'app/helpers/loans_helper.rb', line 269

def loan_total_individuals(loan)
  total = 0
  q = LoanItem.where(loan:)
  from_otu = q.sum(:total)
  from_collection_object = CollectionObject.joins(:loan_items).where(loan_items: {loan:}).sum('collection_objects.total')
  from_otu + from_collection_object
end

#loans_individuals(loans) ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'app/helpers/loans_helper.rb', line 236

def loans_individuals(loans)
  data = {
    otus: 0,
    collection_objects: 0
  }

  q = selected_loan_items(loans)

  data[:otus] = q.where(loan_item_object_type: 'Otu').joins(:loan).sum(:total)

  data[:collection_objects] = q.where(loan_item_object_type: 'CollectionObject')
    .joins(:loan)
    .joins('JOIN collection_objects on collection_objects.id = loan_items.loan_item_object_id')
    .sum('collection_objects.total')
  data
end

#loans_loan_item_disposition(loans) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'app/helpers/loans_helper.rb', line 210

def loans_loan_item_disposition(loans)
  data =  Hash.new(0)

  q = selected_loan_items(loans)

  dispositions = LoanItem.where(project_id: sessions_current_project_id).select('disposition').distinct.pluck(:disposition)

  dispositions.each do |d|
    data[d] = q.where(disposition: d).count
  end

  data['unknown'] = data[nil]
  data.delete(nil)

  data
end

#loans_loan_item_summary(loans) ⇒ Object



294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'app/helpers/loans_helper.rb', line 294

def loans_loan_item_summary(loans)
  a = loans_individuals(loans)
  b = overdue_individuals(loans)

  tag.table do
    [ tag.tr( tag.td('Total')+ tag.td(loans.collect{|a| a.loan_items.count}.sum) ),
      tag.tr( tag.td('CollectionObject items') + tag.td(loans.collect{|a| a.loan_items.where(loan_item_object_type: 'CollectionObject').count}.sum ) ),
      tag.tr( tag.td('OTU items') + tag.td(loans.collect{|a| a.loan_items.where(loan_item_object_type: 'Otu').count}.sum ) ),
      tag.tr( tag.td('Individuals') + tag.td( a[:otus] + a[:collection_objects] ) ),
      tag.tr( tag.td('Unreturned individuals') + tag.td( b[:otus] + b[:collection_objects] ) ),

    ].join.html_safe
  end
end

#loans_per_year(loans, target = :date_sent) ⇒ Object

date_loan_requested, date_received, date_return_expected, date_closed



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'app/helpers/loans_helper.rb', line 110

def loans_per_year(loans, target = :date_sent )
  s,e = loans_start_end_year(loans, target)
  return {} if s.nil? && e.nil?

  data = zeroed_loan_year_hash(s,e)

  loans.select(target).each do |l|
    if y = l.send(target)&.year
      data[y] += 1
    end
  end

  data
end

#loans_search_formObject



55
56
57
# File 'app/helpers/loans_helper.rb', line 55

def loans_search_form
  render('/loans/quick_search_form')
end

#loans_start_end_year(loans, target = :date_sent) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'app/helpers/loans_helper.rb', line 125

def loans_start_end_year(loans, target = :date_sent)
  s = loans.unscope(:select).select("min(#{target}) d").unscope(:order).all[0][:d]&.year
  e = loans.unscope(:select).select("max(#{target}) d").unscope(:order).all[0][:d]&.year

  return [] if s.nil? && e.nil?

  if s && e
  elsif s
    e = s
  else
    s = e
  end
  [s,e]
end

#loans_summary(loans) ⇒ Object



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'app/helpers/loans_helper.rb', line 253

def loans_summary(loans)
  start_year, end_year = loans_start_end_year(loans, target = :date_sent)

  tag.table do
    [ tag.tr( tag.td('Total')+ tag.td(loans.all.count) ),

      tag.tr( tag.td('Year start (date sent)')+ tag.td(start_year) ),
      tag.tr( tag.td('Year end (date sent)')+ tag.td(end_year) ),
      tag.tr( tag.td('Year span')+ tag.td( [end_year, start_year].compact.size == 1 ? (end_year - start_year) : 0) ),

      tag.tr( tag.td('Overdue') + tag.td( loans.overdue.count ) ),
      tag.tr( tag.td('Not overdue') + tag.td( loans.not_overdue.count) ),
    ].join.html_safe
  end
end

#object_loan_history_tag(object) ⇒ Object



69
70
71
# File 'app/helpers/loans_helper.rb', line 69

def object_loan_history_tag(object)
  (:li, "Loaned #{object.times_loaned} times.")
end

#object_loan_status_tag(object) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'app/helpers/loans_helper.rb', line 59

def object_loan_status_tag(object)
  if object.has_loans? && object.has_been_loaned?
    (:h3, 'Loan status') +
      (:ul) do
        (on_loan_tag(object) +
         object_loan_history_tag(object)).html_safe
      end
  end
end

#on_loan_tag(object) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/helpers/loans_helper.rb', line 73

def on_loan_tag(object)
  if object.has_loans? && object.on_loan?
    (:li) do
      ['On ' +  link_to('loan', object.loan) + '.',
       loan_overdue_tag(object.loan),
       loan_due_back_tag(object.loan)
      ].join(' ').html_safe
    end
  else
    ''
  end
end

#overdue_individuals(loans) ⇒ Object



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'app/helpers/loans_helper.rb', line 277

def overdue_individuals(loans)
  data = {
    otus: 0,
    collection_objects: 0
  }

  q = selected_loan_items(loans).where.not(date_returned: nil)

  data[:otus] = q.where(loan_item_object_type: 'Otu').joins(:loan).sum(:total)

  data[:collection_objects] = q.where(loan_item_object_type: 'CollectionObject')
    .joins(:loan)
    .joins('JOIN collection_objects on collection_objects.id = loan_items.loan_item_object_id')
    .sum('collection_objects.total')
  data
end

#selected_loan_items(loans) ⇒ Object



227
228
229
230
231
232
233
234
# File 'app/helpers/loans_helper.rb', line 227

def selected_loan_items(loans)
  s = 'WITH selected_loans AS (' + loans.all.to_sql + ') ' +
    ::LoanItem
    .joins('JOIN selected_loans as selected_loans1 on selected_loans1.id = loan_items.loan_id')
    .to_sql

  ::LoanItem.from('(' + s + ') as loan_items')
end

#zeroed_loan_year_hash(start_year, end_year) ⇒ Object



200
201
202
203
204
205
206
207
208
# File 'app/helpers/loans_helper.rb', line 200

def zeroed_loan_year_hash(start_year, end_year)
  return {} if start_year.blank? || end_year.blank?
  years = {}
  (start_year..end_year).to_a.each do |y|
    years[y] = 0
  end
  years[nil] = 0
  years
end