module EnjuCirculation module EnjuItem def self.included(base) base.extend ClassMethods end module ClassMethods FOR_CHECKOUT_CIRCULATION_STATUS = [ 'Available On Shelf', 'On Loan', 'Waiting To Be Reshelved' ] FOR_CHECKOUT_USE_RESTRICTION = [ 'Available For Supply Without Return', 'Limited Circulation, Long Loan Period', 'Limited Circulation, Short Loan Period', 'No Reproduction', 'Overnight Only', 'Renewals Not Permitted', 'Supervision Required', 'Term Loan', 'User Signature Required', 'Limited Circulation, Normal Loan Period' ] def enju_circulation_item_model include InstanceMethods has_many :reserves, :foreign_key => :manifestation_id scope :for_checkout, -> { includes(:circulation_status, :use_restriction).where( 'circulation_statuses.name' => FOR_CHECKOUT_CIRCULATION_STATUS, 'use_restrictions.name' => FOR_CHECKOUT_USE_RESTRICTION ).where('item_identifier IS NOT NULL') } scope :removed, -> { includes(:circulation_status).where('circulation_statuses.name' => 'Removed') } has_many :checkouts has_many :reserves has_many :checked_items has_many :baskets, :through => :checked_items belongs_to :circulation_status, :validate => true belongs_to :checkout_type has_many :lending_policies, :dependent => :destroy has_one :item_has_use_restriction, :dependent => :destroy has_one :use_restriction, :through => :item_has_use_restriction validates_associated :circulation_status, :checkout_type validates_presence_of :circulation_status, :checkout_type searchable do string :circulation_status do circulation_status.name end end accepts_nested_attributes_for :item_has_use_restriction before_update :delete_lending_policy end end module InstanceMethods def set_circulation_status self.circulation_status = CirculationStatus.where(:name => 'In Process').first if self.circulation_status.nil? end def checkout_status(user) return nil unless user user.profile.user_group.user_group_has_checkout_types.where(:checkout_type_id => self.checkout_type.id).first end def reserved? return true if manifestation.next_reservation false end def rent? return true if self.checkouts.not_returned.select(:item_id).detect{|checkout| checkout.item_id == self.id} false end def reserved_by_user?(user) if manifestation.next_reservation return true if manifestation.next_reservation.user == user end false end def available_for_checkout? if circulation_status.name == 'On Loan' false else manifestation.items.for_checkout.include?(self) end end def checkout!(user) self.circulation_status = CirculationStatus.where(name: 'On Loan').first if reserved_by_user?(user) manifestation.next_reservation.update_attributes(checked_out_at: Time.zone.now) manifestation.next_reservation.transition_to!(:completed) end save! end def checkin! self.circulation_status = CirculationStatus.where(name: 'Available On Shelf').first save(validate: false) end def retain(librarian) self.class.transaction do reservation = manifestation.next_reservation unless reservation.nil? reservation.item = self reservation.transition_to!(:retained) reservation.send_message(librarian) end end end def retained? if manifestation.next_reservation.try(:current_state) == 'retained' and manifestation.next_reservation.item == self return true else false end end def lending_rule(user) policy = lending_policies.where(user_group_id: user.profile.user_group.id).first if policy policy else create_lending_policy(user) end end def not_for_loan? !manifestation.items.for_checkout.include?(self) end def create_lending_policy(user) rule = user.profile.user_group.user_group_has_checkout_types.where(checkout_type_id: checkout_type_id).first return nil unless rule LendingPolicy.create!( item_id: id, user_group_id: rule.user_group_id, fixed_due_date: rule.fixed_due_date, loan_period: rule.checkout_period, renewal: rule.checkout_renewal_limit ) end def delete_lending_policy return nil unless changes[:checkout_type_id] lending_policies.delete_all end def next_reservation Reserve.waiting.where(:item_id => id).first end def latest_checkout checkouts.order('checkouts.id').first end end end end