156 lines
4.9 KiB
Ruby
156 lines
4.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class AppearanceRelease < ApplicationRecord
|
|
include Confirmable
|
|
include Contractable
|
|
include Exploitable
|
|
include Notable
|
|
include Releasable
|
|
include Searchable
|
|
include Signable
|
|
include Syncable
|
|
include Taggable
|
|
include PersonName
|
|
include GuardianPhotoable
|
|
include GuardianName
|
|
|
|
has_one_attached :person_photo
|
|
|
|
composed_of :person_address,
|
|
class_name: 'Address',
|
|
mapping: [
|
|
%w[person_address_street1 street1],
|
|
%w[person_address_street2 street2],
|
|
%w[person_address_city city],
|
|
%w[person_address_state state],
|
|
%w[person_address_zip zip],
|
|
%w[person_address_country country]
|
|
]
|
|
|
|
composed_of :guardian_address,
|
|
class_name: 'Address',
|
|
mapping: [
|
|
%w[guardian_address_street1 street1],
|
|
%w[guardian_address_street2 street2],
|
|
%w[guardian_address_city city],
|
|
%w[guardian_address_state state],
|
|
%w[guardian_address_zip zip],
|
|
%w[guardian_address_country country]
|
|
]
|
|
|
|
|
|
# These validations apply to all releases
|
|
validates :person_email, email: true, allow_blank: true
|
|
validates :person_first_name, :person_last_name, presence: true
|
|
|
|
scope :order_by_name, -> { order(:person_last_name) }
|
|
|
|
def self.random_contract_number
|
|
rand(1_000_000..9_999_998) # random 7 digit number
|
|
end
|
|
|
|
# We don't care for the argument but method WILL receive option name
|
|
# when called from inside with_option block, hence * argument
|
|
def self.face_photo_acceptable_content_types(*)
|
|
['image/png', 'image/jpeg']
|
|
end
|
|
|
|
def self.acceptable_import_file_extensions
|
|
['.png', '.jpeg', '.jpg', '.pdf']
|
|
end
|
|
|
|
# These validations apply to releases being signed by a minor
|
|
with_options if: :minor? do
|
|
validates :guardian_first_name, :guardian_last_name, presence: true
|
|
validates :guardian_email, email: true, allow_blank: true
|
|
end
|
|
|
|
validates :person_photo, content_type: face_photo_acceptable_content_types
|
|
|
|
# These validations apply to releases created natively by the system (i.e. not imported from elsewhere)
|
|
with_options on: :native do
|
|
validates :signature, attached: true
|
|
validates :person_photo, attached: true, content_type: face_photo_acceptable_content_types
|
|
validate :person_photo_is_acceptable, if: :new_record? # Only validate photos on new releases
|
|
end
|
|
|
|
def contract_or_photo_is_attached
|
|
return if person_photo.attached? || contract.attached?
|
|
|
|
errors[:base] << I18n.t('appearance_releases.index.imported_appearance_release_missing_attachment')
|
|
end
|
|
|
|
# These validations apply to releases imported to the system from an outside source
|
|
with_options on: :non_native do
|
|
validate :contract_or_photo_is_attached
|
|
validates :person_photo, content_type: face_photo_acceptable_content_types
|
|
end
|
|
|
|
scope :with_person_photo, -> { joins(:person_photo_attachment) }
|
|
scope :with_person_photo_and_contract, -> { joins(:person_photo_attachment, :contract_attachment) }
|
|
scope :without_person_photo_or_contract, -> { where.not(id: with_person_photo_and_contract) }
|
|
scope :complete, -> { with_person_photo_and_contract }
|
|
scope :incomplete, -> { without_person_photo_or_contract }
|
|
scope :having_no_person_photo, -> { left_joins(:person_photo_attachment).group(:id).having('COUNT(active_storage_attachments) = 0') }
|
|
scope :with_person_name, ->(name) { where('person_first_name ILIKE ? OR person_last_name ILIKE ?', "%#{name}%") }
|
|
|
|
searchable_on %i[
|
|
person_first_name
|
|
person_last_name
|
|
person_address_street1
|
|
person_address_street2
|
|
person_address_city
|
|
person_address_state
|
|
person_address_zip
|
|
person_address_country
|
|
person_email
|
|
person_phone
|
|
]
|
|
|
|
# All releases must respond to the following messages
|
|
def name
|
|
person_name
|
|
end
|
|
|
|
def filename_suffix
|
|
"#{person_last_name} #{person_first_name}"
|
|
end
|
|
|
|
def photo
|
|
person_photo
|
|
end
|
|
|
|
def photos
|
|
photo.attached? ? [photo] : []
|
|
end
|
|
|
|
def contact_person
|
|
@contact_person ||= Contact.new(name, person_address, person_email, person_phone)
|
|
end
|
|
|
|
def uses_edl?
|
|
true
|
|
end
|
|
|
|
def contract_file_name
|
|
"#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime('%Y.%m.%d')}_#{release_number}_#{filename_suffix.parameterize}"
|
|
end
|
|
|
|
private
|
|
|
|
# Validates the quality of the person photo
|
|
def person_photo_is_acceptable
|
|
return unless person_photo.attached?
|
|
|
|
# Call a remote API to perform the validation
|
|
image_validation = BrayniacAI::Validation.create(bucket_name: ENV['AWS_BUCKET'], object_name: person_photo.key)
|
|
|
|
unless image_validation.valid
|
|
errors.add(:person_photo, image_validation.error)
|
|
end
|
|
rescue ActiveResource::ConnectionError => e
|
|
# TODO
|
|
Rails.logger.error(e)
|
|
end
|
|
end
|