require "nokogiri" require "skala/adapter/get_user_transactions" require_relative "../aleph_adapter" require_relative "./resolve_user" class Skala::AlephAdapter::GetUserTransactions < Skala::Adapter::GetUserTransactions include parent::ResolveUser def call(username, options = {}) resolved_user_id = resolve_user(username) patron_cash_list = @adapter.restful_api.patron(resolved_user_id).circulationActions.cash.get(view: :full) patron_loan_list = @adapter.restful_api.patron(resolved_user_id).circulationActions.loans.get(view: :full) if [patron_cash_list, patron_loan_list].any? { |_response| _response.include?("") } return nil else transactions = [] # regular credits/debits Nokogiri::XML(patron_cash_list).xpath("//cash").each do |_cash| credit_or_debit = { id: id(_cash), creation_date: creation_date(_cash), record: { id: record_id(_cash) }, reason: reason(_cash), type: type(_cash), value: value(_cash), description: description(_cash) } transactions << credit_or_debit end # unentered debits from loans Nokogiri::XML(patron_loan_list).xpath("//loan").each do |_loan| if fine = _loan.at_xpath("./fine").try(:content).presence transactions << { id: nil, record: { id: record_id(_loan) }, reason: :overdue_fine, type: :debit, value: fine.to_f } end end self.class::Result.new( transactions: transactions, source: [patron_cash_list, patron_loan_list] ) end end private def creation_date(cash) if date = cash.at_xpath("./z31/z31-date").try(:content).presence Date.strptime(date, "%Y%m%d") end end def id(cash) cash.attr("href")[/[^\/]+\Z/][/\A[^?]+/] end def record_id(element) element.at_xpath("./z13/z13-doc-number").try(:content).presence end def reason(cash) case cash.at_xpath("./z31/z31-type").try(:content).presence when /Kopierauftrag/ then :photocopy_request when /Überfällig/ then :overdue_fine end end def type(cash) case cash.attr("type") when "credit" then :credit when "debit" then :debit end end def description(cash) cash.at_xpath("./z31/z31-description").try(:content).presence end def value(cash) cash.at_xpath("./z31/z31-sum").try(:content).try(:[], /\d+.\d+/).try(:to_f) end end