app/models/agent.rb
# -*- encoding: utf-8 -*-
class Agent < ActiveRecord::Base
attr_accessible :last_name, :middle_name, :first_name,
:last_name_transcription, :middle_name_transcription,
:first_name_transcription, :corporate_name, :corporate_name_transcription,
:full_name, :full_name_transcription, :full_name_alternative, :zip_code_1,
:zip_code_2, :address_1, :address_2, :address_1_note, :address_2_note,
:telephone_number_1, :telephone_number_2, :fax_number_1, :fax_number_2,
:other_designation, :place, :street, :locality, :region, :language_id,
:country_id, :agent_type_id, :note, :required_role_id, :email, :email_2, :url,
:full_name_alternative_transcription, :title, :birth_date, :death_date,
:agent_identifier,
:telephone_number_1_type_id, :extelephone_number_1,
:extelephone_number_1_type_id, :fax_number_1_type_id,
:telephone_number_2_type_id, :extelephone_number_2,
:extelephone_number_2_type_id, :fax_number_2_type_id, :user_username,
:exclude_state, :keyperson_1, :keyperson_2, :corporate_type_id, :place_id,
:grade_id, :gender_id
scope :readable_by, lambda{|user| {:conditions => ['required_role_id <= ?', user.try(:user_has_role).try(:role_id) || Role.where(:name => 'Guest').select(:id).first.id]}}
has_many :creates, :dependent => :destroy
has_many :works, :through => :creates
has_many :realizes, :dependent => :destroy
has_many :expressions, :through => :realizes
has_many :produces, :dependent => :destroy
has_many :manifestations, :through => :produces
has_many :children, :foreign_key => 'parent_id', :class_name => 'AgentRelationship', :dependent => :destroy
has_many :parents, :foreign_key => 'child_id', :class_name => 'AgentRelationship', :dependent => :destroy
has_many :derived_agents, :through => :children, :source => :child
has_many :original_agents, :through => :parents, :source => :parent
has_many :picture_files, :as => :picture_attachable, :dependent => :destroy
has_many :donates #TODO :dependent => :destroy が無いため、agentを削除や統合した場合、レコードが残る
has_many :donated_items, :through => :donates, :source => :item
has_many :owns, :dependent => :destroy
has_many :items, :through => :owns
has_many :agent_merges, :dependent => :destroy
has_many :agent_merge_lists, :through => :agent_merges
has_many :agent_aliases, :dependent => :destroy
belongs_to :user
belongs_to :agent_type
belongs_to :required_role, :class_name => 'Role', :foreign_key => 'required_role_id', :validate => true
belongs_to :language
belongs_to :country
belongs_to :place, :class_name => 'Subject', :foreign_key => 'place_id'
belongs_to :corporate_type, :class_name => 'Keycode', :foreign_key => 'corporate_type_id'
belongs_to :gender, :class_name => 'Keycode', :foreign_key => 'gender_id'
belongs_to :grade, :class_name => 'Keycode', :foreign_key => 'grade_id'
has_one :agent_import_result
has_many :orders
accepts_nested_attributes_for :agent_aliases
attr_accessible :agent_aliases_attributes
validates_presence_of :language, :agent_type, :country
validates_associated :language, :agent_type, :country
validates :full_name, :presence => true, :length => {:maximum => 255}
validates :user_id, :uniqueness => true, :allow_nil => true
validates :birth_date, :format => {:with => /^\d+(-\d{0,2}){0,2}$/}, :allow_blank => true
validates :death_date, :format => {:with => /^\d+(-\d{0,2}){0,2}$/}, :allow_blank => true
validates :email, :format => {:with => /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i}, :allow_blank => true
validates :email_2, :format => {:with => /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i}, :allow_blank => true
validate :check_birth_date
# validate :check_full_name
before_validation :set_role_and_name, :set_date_of_birth, :set_date_of_death
before_save :change_note, :mark_destroy_blank_full_name
# ManifestationsController#index の manifestation をキャッシュしているため
# 著者・協力者・出版者のフルネーム変更時は manifestation.updated_at を更新する
after_update :touch_manifestation, :if => lambda{ self.full_name_changed? || self.required_role_id_changed?}
def touch_manifestation
self.works.map{|w| w.touch}
self.realizes.map{|r| r.touch}
self.expressions.map{|e| e.touch}
end
validate :check_duplicate_user
has_paper_trail
attr_accessor :user_username
#[:address_1, :address_2].each do |column|
# encrypt_with_public_key column,
# :key_pair => File.join(Rails.root.to_s,'config','keypair.pem'),
# :base64 => true
#end
searchable do
text :name, :place, :address_1, :address_2, :other_designation, :note
string :last_name
string :first_name
string :last_name_transcription
string :first_name_transcription
string :full_name
string :full_name_transcription
string :full_name_alternative
string :telephone_number_1
string :telephone_number_2
string :extelephone_number_1
string :extelephone_number_2
string :fax_number_1
string :fax_number_2
string :zip_code_1
string :zip_code_2
string :place
string :address_1
string :address_2
string :other_designation
string :note
string :username do
user.username if user
end
string :agent_type do
agent_type.name
end
time :created_at
time :updated_at
time :date_of_birth
time :date_of_death
string :user
integer :work_ids, :multiple => true
integer :expression_ids, :multiple => true
integer :manifestation_ids, :multiple => true
integer :agent_merge_list_ids, :multiple => true
integer :derived_agent_ids, :multiple => true
integer :original_agent_ids, :multiple => true
integer :required_role_id
integer :agent_type_id
integer :user_id
integer :exclude_state
integer :id
AgentRelationshipType.pluck(:id).each do |type_id|
integer 'relationship_type_parent_' + type_id.to_s , :multiple => true do
parents.select_type_id(type_id).pluck(:parent_id)
end
integer 'relationship_type_child_' + type_id.to_s , :multiple => true do
children.select_type_id(type_id).pluck(:child_id)
end
end if AgentRelationshipType.table_exists?
end
paginates_per 10
def mark_destroy_blank_full_name
agent_aliases.each do |agent_alias|
agent_alias.mark_for_destruction if agent_alias.full_name.blank? and agent_alias.full_name_transcription.blank? and agent_alias.full_name_alternative.blank?
end
end
def full_name_without_space
full_name.gsub(/\s/, "")
end
def set_role_and_name
self.required_role = Role.where(:name => 'Librarian').first if self.required_role_id.nil?
set_full_name
end
def set_full_name
#puts "@@@"
#puts self
#puts "@@@"
if self.full_name.blank?
if self.last_name.to_s.strip and self.first_name.to_s.strip and SystemConfiguration.get("family_name_first") == true
self.full_name = [last_name, middle_name, first_name].compact.join(" ").to_s.strip
else
self.full_name = [first_name, last_name, middle_name].compact.join(" ").to_s.strip
end
end
if self.full_name_transcription.blank?
self.full_name_transcription = [last_name_transcription, middle_name_transcription, first_name_transcription].join(" ").to_s.strip
end
[self.full_name, self.full_name_transcription]
end
def set_date_of_birth
if birth_date.blank?
date = nil
else
begin
date = Time.zone.parse("#{birth_date}")
rescue ArgumentError
begin
date = Time.zone.parse("#{birth_date}-01")
rescue ArgumentError
begin
date = Time.zone.parse("#{birth_date}-01-01")
rescue
nil
end
end
end
end
self.date_of_birth = date
end
def set_date_of_death
if death_date.blank?
date = nil
else
begin
date = Time.zone.parse("#{death_date}")
rescue ArgumentError
begin
date = Time.zone.parse("#{death_date}-01")
rescue ArgumentError
begin
date = Time.zone.parse("#{death_date}-01-01")
rescue
nil
end
end
end
end
self.date_of_death = date
end
def check_birth_date
if date_of_birth.present? and date_of_death.present?
if date_of_birth > date_of_death
errors.add(:birth_date)
errors.add(:death_date)
end
end
end
def check_full_name
return unless full_name
return if user
agents = Agent.where("full_name = ? AND user_id IS NULL", full_name)
errors.add(:full_name, I18n.t('errors.messages.taken')) unless agents.blank?
end
#def full_name_generate
# # TODO: 日本人以外は?
# name = []
# name << self.last_name.to_s.strip
# name << self.middle_name.to_s.strip unless self.middle_name.blank?
# name << self.first_name.to_s.strip
# name << self.corporate_name.to_s.strip
# name.join(" ").strip
#end
def full_name_transcription_without_space
full_name_transcription.to_s.gsub(/\s/, "")
end
def full_name_alternative_without_space
full_name_alternative.to_s.gsub(/\s/, "")
end
def name
name = []
name << full_name.to_s.strip
name << full_name_transcription.to_s.strip
name << full_name_alternative.to_s.strip
#name << full_name_without_space
#name << full_name_transcription_without_space
#name << full_name_alternative_without_space
#name << full_name.wakati rescue nil
#name << full_name_transcription.wakati rescue nil
#name << full_name_alternative.wakati rescue nil
name
end
def date
if date_of_birth
if date_of_death
"#{date_of_birth} - #{date_of_death}"
else
"#{date_of_birth} -"
end
end
end
def creator?(resource)
resource.creators.include?(self)
end
def publisher?(resource)
resource.publishers.include?(self)
end
def check_required_role(user)
return true if self.user.blank?
return true if self.user.required_role.name == 'Guest'
return true if user == self.user
return true if user.has_role?(self.user.required_role.name)
false
rescue NoMethodError
false
end
def created(work)
creates.where(:work_id => work.id).first
end
def realized(expression)
realizes.where(:expression_id => expression.id).first
end
def produced(manifestation)
produces.where(:manifestation_id => manifestation.id).first
end
def owned(item)
owns.where(:item_id => item.id)
end
def self.import_agents(agent_lists, options = {})
list = []
return list if agent_lists.blank?
options[:language_id] ||= 1
agent_lists.uniq.compact.each do |attrs|
agent = add_agent(attrs[:full_name], attrs[:full_name_transcription], options)
next if agent.blank?
list << agent if agent
end
list
end
def self.add_agents(agent_names, agent_transcriptions = nil, options = {})
return [] if agent_names.blank?
names = agent_names.gsub(';', ';').split(/;/)
if agent_transcriptions.nil?
transcriptions = []
elsif agent_transcriptions == ''
transcriptions = ['']
else
transcriptions = agent_transcriptions.gsub(';', ';').split(/;/, -names.size)
end
list = []
names.compact.each_with_index do |name, i|
agent = add_agent(name, transcriptions[i], options)
next if agent.blank?
list << agent
end
list.uniq
end
# options:
# :create_new: 新規作成をするかどうかの指定(デフォルトはtrue)
# その他: 新規作成時の属性値(更新には使用されない)
def self.add_agent(name, transcription = nil, options = {})
if options.include?(:create_new)
create_new = options.delete(:create_new)
else
create_new = true # 特に指定がなければ新規作成もする
end
name = name.try(:exstrip_with_full_size_space)
return {} if name.blank?
agent = Agent.where(full_name: name).first
transcription = transcription.try(:exstrip_with_full_size_space)
if agent.blank? && create_new
agent = Agent.new(options.merge(full_name: name))
agent.full_name_transcription = transcription if transcription
exclude_agents = SystemConfiguration.get("exclude_agents").split(',').map {|word| word.gsub(/^[ \s]*(.*?)[ \s]*$/, '\1') }
agent.exclude_state = 1 if exclude_agents.include?(name)
agent.save
else
if transcription
agent.full_name_transcription = transcription
agent.save
end
end
agent
end
def agents
self.original_agents + self.derived_agents
end
def self.create_with_user(params, user)
agent = Agent.new(params)
#agent.full_name = user.username if agent.full_name.blank?
agent.email = user.email
agent.required_role = Role.find(:first, :conditions => ['name=?', "Librarian"]) rescue nil
agent.language = Language.find(:first, :conditions => ['iso_639_1=?', user.locale]) rescue nil
agent
end
def change_note
data = Agent.find(self.id).note rescue nil
unless data == self.note
self.note_update_at = Time.zone.now
if User.current_user.nil?
#TODO
self.note_update_by = "SYSTEM"
self.note_update_library = "SYSTEM"
else
self.note_update_by = User.current_user.agent.full_name
self.note_update_library = Library.find(User.current_user.library_id).display_name
end
end
end
private
def check_duplicate_user
return if SystemConfiguration.get("agent.check_duplicate_user").nil? || SystemConfiguration.get("agent.check_duplicate_user") == false
return if self.full_name_transcription.blank? or self.birth_date.blank? or self.telephone_number_1.blank?
chash = {}
chash[:full_name_transcription] = self.full_name_transcription.strip
chash[:birth_date] = self.birth_date
chash[:telephone_number_1] = self.telephone_number_1
agents = Agent.find(:all, :conditions => chash)
agents.delete_if { |p| p.id == self.id }
if self.new_record?
errors.add(:base, I18n.t('agent.duplicate_user')) if agents.size > 0
end
#logger.info errors.inspect
end
end
# == Schema Information
#
# Table name: agents
#
# id :integer not null, primary key
# user_id :integer
# last_name :string(255)
# middle_name :string(255)
# first_name :string(255)
# last_name_transcription :string(255)
# middle_name_transcription :string(255)
# first_name_transcription :string(255)
# corporate_name :string(255)
# corporate_name_transcription :string(255)
# full_name :string(255)
# full_name_transcription :text
# full_name_alternative :text
# created_at :datetime
# updated_at :datetime
# deleted_at :datetime
# zip_code_1 :string(255)
# zip_code_2 :string(255)
# address_1 :text
# address_2 :text
# address_1_note :text
# address_2_note :text
# telephone_number_1 :string(255)
# telephone_number_2 :string(255)
# fax_number_1 :string(255)
# fax_number_2 :string(255)
# other_designation :text
# place :text
# street :text
# locality :text
# region :text
# date_of_birth :datetime
# date_of_death :datetime
# language_id :integer default(1), not null
# country_id :integer default(1), not null
# agent_type_id :integer default(1), not null
# lock_version :integer default(0), not null
# note :text
# creates_count :integer default(0), not null
# realizes_count :integer default(0), not null
# produces_count :integer default(0), not null
# owns_count :integer default(0), not null
# required_role_id :integer default(1), not null
# required_score :integer default(0), not null
# state :string(255)
# email :text
# url :text
# full_name_alternative_transcription :text
# title :string(255)
# birth_date :string(255)
# death_date :string(255)
# address_1_key :binary
# address_1_iv :binary
# address_2_key :binary
# address_2_iv :binary
# telephone_number_key :binary
# telephone_number_iv :binary
#