Class: Loan
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Loan
- Includes:
- Housekeeping, Shared::DataAttributes, Shared::Depictions, Shared::Documentation, Shared::HasPapertrail, Shared::Identifiers, Shared::IsData, Shared::Notes, Shared::Tags, SoftValidation
- Defined in:
- app/models/loan.rb
Overview
A Loan is the metadata that wraps/describes an exchange of specimens.
TODO: Turn into a proper subclass when github.com/SpeciesFileGroup/taxonworks/issues/2120 implemented.
Constant Summary collapse
- CLONED_ATTRIBUTES =
[ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze
Constants included from SoftValidation
SoftValidation::ANCESTORS_WITH_SOFT_VALIDATIONS
Instance Attribute Summary collapse
-
#clone_from ⇒ Object
A Loan#id, when present values from that record are copied from the referenced loan, when not otherwised populated.
-
#date_closed ⇒ DateTime
Date at which loan has been fully resolved and requires no additional attention.
-
#date_received ⇒ DateTime
Date loan was recievied by recipient.
-
#date_requested ⇒ DateTime
Date request was received by lender.
-
#date_return_expected ⇒ DateTime
Date expected.
-
#date_sent ⇒ DateTime
Date loan was delivered to post.
-
#is_gift ⇒ Boolean?
When true then no return is expected.
-
#project_id ⇒ Integer
the project ID.
-
#recipient_address ⇒ String
Address loan sent to.
- #recipient_country ⇒ String
-
#recipient_email ⇒ String
Email address of recipient.
-
#recipient_honorific ⇒ String
As in Prof.
-
#recipient_phone ⇒ String
Phone number of recipient.
-
#request_method ⇒ String
Brief not as to how the request was made, not a controlled vocabulary.
-
#supervisor_email ⇒ String
Oe email of utlimately responsible party if recient can not be.
-
#supervisor_phone ⇒ String
Phone # of utlimately responsible party if recient can not be.
Class Method Summary collapse
- .select_optimized(user_id, project_id) ⇒ Object
-
.used_recently(project_id) ⇒ Scope
The max 10 most recently used loans.
Instance Method Summary collapse
- #clone_attributes ⇒ Object protected
-
#collection_object_ids ⇒ Array
Collection_object ids.
-
#collection_objects ⇒ Scope
Of CollectionObject.
- #contains_types? ⇒ Boolean
- #days_overdue ⇒ Integer?
- #days_until_due ⇒ Integer, false
- #families ⇒ Object
- #gift_or_date_expected_required ⇒ Object protected
- #overdue? ⇒ Boolean?
- #received_after_closed ⇒ Object protected
- #received_after_expected ⇒ Object protected
- #reject_loan_items(attributed) ⇒ Object protected
- #requested_after_closed ⇒ Object protected
- #requested_after_expected ⇒ Object protected
- #requested_after_received ⇒ Object protected
- #requested_after_sent ⇒ Object protected
-
#return! ⇒ Object
protected
Not used externally.
- #sent_after_closed ⇒ Object protected
- #sent_after_expected ⇒ Object protected
- #sent_after_received ⇒ Object protected
- #sv_missing_documentation ⇒ Object protected
Methods included from Shared::IsData
#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_destroyable?, #is_editable?, #is_in_use?, #is_in_users_projects?, #metamorphosize, #similar
Methods included from Shared::HasPapertrail
#attribute_updated, #attribute_updater
Methods included from Shared::Documentation
#document_array=, #documented?, #reject_documentation, #reject_documents
Methods included from Shared::Depictions
#has_depictions?, #image_array=, #reject_depictions, #reject_images
Methods included from SoftValidation
#clear_soft_validations, #fix_for, #fix_soft_validations, #soft_fixed?, #soft_valid?, #soft_validate, #soft_validated?, #soft_validations, #soft_validators
Methods included from Shared::Tags
#reject_tags, #tag_with, #tagged?, #tagged_with?
Methods included from Shared::Notes
#concatenated_notes_string, #reject_notes
Methods included from Shared::Identifiers
#dwc_occurrence_id, #identified?, #next_by_identifier, #previous_by_identifier, #reject_identifiers, #uri, #uuid
Methods included from Shared::DataAttributes
#import_attributes, #internal_attributes, #keyword_value_hash, #reject_data_attributes
Methods included from Housekeeping
#has_polymorphic_relationship?
Methods inherited from ApplicationRecord
Instance Attribute Details
#clone_from ⇒ Object
A Loan#id, when present values from that record are copied from the referenced loan, when not otherwised populated
91 92 93 |
# File 'app/models/loan.rb', line 91 def clone_from @clone_from end |
#date_closed ⇒ DateTime
Returns date at which loan has been fully resolved and requires no additional attention.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#date_received ⇒ DateTime
Returns date loan was recievied by recipient.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#date_requested ⇒ DateTime
Returns date request was received by lender.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#date_return_expected ⇒ DateTime
Returns date expected.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#date_sent ⇒ DateTime
Returns date loan was delivered to post.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#is_gift ⇒ Boolean?
Returns when true then no return is expected.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#project_id ⇒ Integer
the project ID
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#recipient_address ⇒ String
Returns address loan sent to.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#recipient_country ⇒ String
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#recipient_email ⇒ String
Returns email address of recipient.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#recipient_honorific ⇒ String
Returns as in Prof. Mrs. Dr. M. Mr. etc.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#recipient_phone ⇒ String
Returns phone number of recipient.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#request_method ⇒ String
Returns brief not as to how the request was made, not a controlled vocabulary.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#supervisor_email ⇒ String
Returns oe email of utlimately responsible party if recient can not be.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
#supervisor_phone ⇒ String
Returns phone # of utlimately responsible party if recient can not be.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'app/models/loan.rb', line 62 class Loan < ApplicationRecord include Housekeeping include Shared::DataAttributes include Shared::Identifiers include Shared::Notes include Shared::Tags include SoftValidation include Shared::Depictions include Shared::Documentation include Shared::HasPapertrail include Shared::IsData ignore_whitespace_on(:lender_address, :recipient_address) CLONED_ATTRIBUTES = [ :lender_address, :recipient_address, :recipient_email, :recipient_phone, :recipient_country, :supervisor_email, :supervisor_phone, :recipient_honorific, ].freeze # A Loan#id, when present values # from that record are copied # from the referenced loan, when # not otherwised populated attr_accessor :clone_from after_initialize :clone_attributes, if: Proc.new{|l| l.clone_from.present? && l.new_record? } has_many :loan_items, dependent: :restrict_with_error, inverse_of: :loan has_many :loan_recipient_roles, class_name: 'LoanRecipient', as: :role_object, inverse_of: :role_object has_many :loan_supervisor_roles, class_name: 'LoanSupervisor', as: :role_object, inverse_of: :role_object has_many :loan_recipients, through: :loan_recipient_roles, source: :person has_many :loan_supervisors, through: :loan_supervisor_roles, source: :person # This is not defined in HasRoles has_many :people, through: :roles not_super = lambda {supervisor_email.present?} validates :supervisor_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :recipient_email, format: {with: User::VALID_EMAIL_REGEX}, if: not_super validates :lender_address, presence: true validate :requested_after_sent validate :requested_after_received validate :requested_after_expected validate :requested_after_closed validate :sent_after_received validate :sent_after_expected validate :sent_after_closed validate :received_after_closed validate :received_after_expected validate :gift_or_date_expected_required soft_validate( :sv_missing_documentation, set: :missing_documentation, name: 'Missing documentation', description: 'No documnets') accepts_nested_attributes_for :loan_items, allow_destroy: true, reject_if: :reject_loan_items accepts_nested_attributes_for :loan_supervisors, :loan_supervisor_roles, allow_destroy: true accepts_nested_attributes_for :loan_recipients, :loan_recipient_roles, allow_destroy: true scope :overdue, -> {where('now() > loans.date_return_expected AND date_closed IS NULL')} scope :not_overdue, -> {where('now() < loans.date_return_expected AND date_closed IS NULL')} # @return [Scope] of CollectionObject def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end # @return [Boolean, nil] def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end # @return [Integer, nil] def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end # @return [Integer, false] def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end # @return [Array] collection_object ids def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end # @return [Scope] # the max 10 most recently used loans def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end def families end protected # Not used externally def return! loan_items.update_all(date_returned: Time.current) end def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end end |
Class Method Details
.select_optimized(user_id, project_id) ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'app/models/loan.rb', line 213 def self.select_optimized(user_id, project_id) r = used_recently(project_id) h = { quick: [], pinboard: Loan.pinned_by(user_id).where(project_id:).to_a, recent: [] } if r.empty? h[:quick] = Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a else h[:recent] = Loan.where(id: r.first(10)).to_a h[:quick] = (Loan.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a + Loan.where(id: r.first(4)).to_a).uniq end h end |
.used_recently(project_id) ⇒ Scope
Returns the max 10 most recently used loans.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'app/models/loan.rb', line 189 def self.used_recently(project_id) a = Loan.where(project_id:, updated_at: (3.weeks.ago..1.day.from_now)) .select(:loan_id).order(updated_at: :desc).limit(5).pluck(:id) t = LoanItem.arel_table k = Loan.arel_table # i is a select manager i = t.project(t['loan_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 3.weeks.ago )) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # z is a table alias z = i.as('recent_t') b = Loan.joins( Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['loan_id'].eq(k['id']))) ).pluck(:loan_id).uniq (a + b).uniq end |
Instance Method Details
#clone_attributes ⇒ Object (protected)
248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'app/models/loan.rb', line 248 def clone_attributes l = Loan.find(clone_from) CLONED_ATTRIBUTES.each do |a| write_attribute(a, l.send(a)) end l.loan_recipients.each do |p| roles.build(type: 'LoanRecipient', person: p) end l.loan_supervisors.each do |p| roles.build(type: 'LoanSupervisor', person: p) end end |
#collection_object_ids ⇒ Array
Returns collection_object ids.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'app/models/loan.rb', line 171 def collection_object_ids retval = [] loan_items.each do |li| case li.loan_item_object_type when 'Container' retval += li.loan_item_object.all_collection_object_ids when 'CollectionObject' retval.push(li.loan_item_object_id) when 'Otu' retval += li.loan_item_object.collection_objects.pluck(:id) else end end retval end |
#collection_objects ⇒ Scope
Returns of CollectionObject.
138 139 140 141 142 143 144 145 |
# File 'app/models/loan.rb', line 138 def collection_objects list = collection_object_ids if list.empty? CollectionObject.where('false') else CollectionObject.find(list) end end |
#contains_types? ⇒ Boolean
231 232 233 234 235 236 |
# File 'app/models/loan.rb', line 231 def contains_types? collection_objects.each do |c| return true if c.type_materials.any? end false end |
#days_overdue ⇒ Integer?
157 158 159 160 161 162 163 |
# File 'app/models/loan.rb', line 157 def days_overdue if date_return_expected.present? (Time.current.to_date - date_return_expected).to_i else nil end end |
#days_until_due ⇒ Integer, false
166 167 168 |
# File 'app/models/loan.rb', line 166 def days_until_due date_return_expected && (date_return_expected - Time.current.to_date ).to_i end |
#families ⇒ Object
238 239 |
# File 'app/models/loan.rb', line 238 def families end |
#gift_or_date_expected_required ⇒ Object (protected)
263 264 265 |
# File 'app/models/loan.rb', line 263 def gift_or_date_expected_required errors.add(:date_return_expected, ' or gift status is required') if is_gift.blank? && date_return_expected.nil? end |
#overdue? ⇒ Boolean?
148 149 150 151 152 153 154 |
# File 'app/models/loan.rb', line 148 def overdue? if date_return_expected.present? Time.current.to_date > date_return_expected && date_closed.blank? else nil end end |
#received_after_closed ⇒ Object (protected)
295 296 297 |
# File 'app/models/loan.rb', line 295 def received_after_closed errors.add(:date_received, 'must be closed after received') if date_closed.present? && date_received.present? && date_closed < date_received end |
#received_after_expected ⇒ Object (protected)
299 300 301 |
# File 'app/models/loan.rb', line 299 def received_after_expected errors.add(:date_received, 'must be expected after received') if date_return_expected.present? && date_received.present? && date_return_expected < date_received end |
#reject_loan_items(attributed) ⇒ Object (protected)
303 304 305 |
# File 'app/models/loan.rb', line 303 def reject_loan_items(attributed) attributed['global_entity'].blank? && (attributed['loan_item_object_type'].blank? && attributed['loan_item_object_id'].blank?) end |
#requested_after_closed ⇒ Object (protected)
279 280 281 |
# File 'app/models/loan.rb', line 279 def requested_after_closed errors.add(:date_requested, 'must be closed after requested') if date_requested.present? && date_closed.present? && date_closed < date_requested end |
#requested_after_expected ⇒ Object (protected)
275 276 277 |
# File 'app/models/loan.rb', line 275 def requested_after_expected errors.add(:date_requested, 'must be expected after requested') if date_requested.present? && date_return_expected.present? && date_return_expected < date_requested end |
#requested_after_received ⇒ Object (protected)
271 272 273 |
# File 'app/models/loan.rb', line 271 def requested_after_received errors.add(:date_requested, 'must be received after requested') if date_requested.present? && date_received.present? && date_received < date_requested end |
#requested_after_sent ⇒ Object (protected)
267 268 269 |
# File 'app/models/loan.rb', line 267 def requested_after_sent errors.add(:date_requested, 'must be sent after requested') if date_requested.present? && date_sent.present? && date_sent < date_requested end |
#return! ⇒ Object (protected)
Not used externally
244 245 246 |
# File 'app/models/loan.rb', line 244 def return! loan_items.update_all(date_returned: Time.current) end |
#sent_after_closed ⇒ Object (protected)
291 292 293 |
# File 'app/models/loan.rb', line 291 def sent_after_closed errors.add(:date_sent, 'must be closed after sent') if date_sent.present? && date_closed.present? && date_closed < date_sent end |
#sent_after_expected ⇒ Object (protected)
287 288 289 |
# File 'app/models/loan.rb', line 287 def sent_after_expected errors.add(:date_sent, 'must be expected after sent') if date_sent.present? && date_return_expected.present? && date_return_expected < date_sent end |
#sent_after_received ⇒ Object (protected)
283 284 285 |
# File 'app/models/loan.rb', line 283 def sent_after_received errors.add(:date_sent, 'must be received after sent') if date_sent.present? && date_received.present? && date_received < date_sent end |
#sv_missing_documentation ⇒ Object (protected)
307 308 309 |
# File 'app/models/loan.rb', line 307 def sv_missing_documentation soft_validations.add(:base, 'No documents') unless self.documents.any? end |