<commit_before>#-------------------------------------------------------------------------------
#
# Asset
#
# Base class for all assets. This class represents a generic asset, subclasses represent concrete
# asset types.
#
#-------------------------------------------------------------------------------
class Asset < ActiveRecord::Base

  OBJECT_CACHE_EXPIRE_SECONDS = Rails.application.config.object_cache_expire_seconds
  # The policy analyzer to use comes from the Rails config
  POLICY_ANALYZER = Rails.application.config.policy_analyzer

  #-----------------------------------------------------------------------------
  # Behaviors
  #-----------------------------------------------------------------------------
  include TransamObjectKey
  include TransamNumericSanitizers
  include FiscalYear

  #-----------------------------------------------------------------------------
  # Callbacks
  #-----------------------------------------------------------------------------
  after_initialize  :set_defaults

  # Clean up any HABTM associations before the asset is destroyed
  before_destroy { asset_groups.clear }

  # Before the asset is updated we may need to update things like estimated
  # replacement cost if they updated other things
  before_update   :before_update_callback, :except => :create

  before_update :clear_cache

  #-----------------------------------------------------------------------------
  # Associations common to all asset types
  #-----------------------------------------------------------------------------

  # each asset belongs to a single organization
  belongs_to  :organization

  # each asset has a single asset type
  belongs_to  :asset_type

  # each asset has a single asset subtype
  belongs_to  :asset_subtype

  # each asset has a single maintenance provider type
  belongs_to  :maintenance_provider_type

  # each asset has a reason why it is being replaced
  belongs_to  :replacement_reason_type

  # each was puchased from a vendor
  belongs_to  :vendor

  # each belongs to a single manufacturer
  belongs_to  :manufacturer

  # each can belong to a parent
  belongs_to  :parent, :class_name => "Asset",  :foreign_key => :parent_id

  # Each asset has zero or more asset events. These are all events regardless of
  # event type. Events are deleted when the asset is deleted
  has_many   :asset_events, :dependent => :destroy

  # each asset has zero or more condition updates
  has_many   :condition_updates, -> {where :asset_event_type_id => ConditionUpdateEvent.asset_event_type.id }, :class_name => "ConditionUpdateEvent"

  # each asset has zero or more scheduled replacement updates
  has_many   :schedule_replacement_updates, -> {where :asset_event_type_id => ScheduleReplacementUpdateEvent.asset_event_type.id }, :class_name => "ScheduleReplacementUpdateEvent"

  # each asset has zero or more scheduled rehabilitation updates
  has_many   :schedule_rehabilitation_updates, -> {where :asset_event_type_id => ScheduleRehabilitationUpdateEvent.asset_event_type.id }, :class_name => "ScheduleRehabilitationUpdateEvent"

  # each asset has zero or more recorded rehabilitation events
  has_many   :rehabilitation_updates, -> {where :asset_event_type_id => RehabilitationUpdateEvent.asset_event_type.id}, :class_name => "RehabilitationUpdateEvent"

  # each asset has zero or more scheduled disposition updates
  has_many   :schedule_disposition_updates, -> {where :asset_event_type_id => ScheduleDispositionUpdateEvent.asset_event_type.id }, :class_name => "ScheduleDispositionUpdateEvent"

  # each asset has zero or more service status updates
  has_many   :service_status_updates, -> {where :asset_event_type_id => ServiceStatusUpdateEvent.asset_event_type.id }, :class_name => "ServiceStatusUpdateEvent"

  # each asset has zero or more disposition updates
  has_many   :disposition_updates, -> {where :asset_event_type_id => DispositionUpdateEvent.asset_event_type.id }, :class_name => "DispositionUpdateEvent"

  # each asset has zero or more early disposition requests
  has_many   :early_disposition_requests, -> {where :asset_event_type_id => EarlyDispositionRequestUpdateEvent.asset_event_type.id }, :class_name => "EarlyDispositionRequestUpdateEvent"

  # each asset has zero or more location updates.
  has_many   :location_updates, -> {where :asset_event_type_id => LocationUpdateEvent.asset_event_type.id }, :class_name => "LocationUpdateEvent"

  # Each asset has zero or more images. Images are deleted when the asset is deleted
  has_many    :images,      :as => :imagable,       :dependent => :destroy

  # Each asset has zero or more documents. Documents are deleted when the asset is deleted
  has_many    :documents,   :as => :documentable, :dependent => :destroy

  # Each asset has zero or more comments. Documents are deleted when the asset is deleted
  has_many    :comments,    :as => :commentable,  :dependent => :destroy

  # Each asset has zero or more tasks. Tasks are deleted when the asset is deleted
  has_many    :tasks,       :as => :taskable,     :dependent => :destroy

  # Each asset can have 0 or more dependents
  has_many    :dependents,  :class_name => 'Asset', :foreign_key => :parent_id, :dependent => :nullify

  # Each asset can be associated with 0 or more asset groups
  has_and_belongs_to_many :asset_groups

  # Each asset was created and updated by a user
  belongs_to :creator, :class_name => "User", :foreign_key => :created_by_id
  belongs_to :updator, :class_name => "User", :foreign_key => :updated_by_id

  # Has been tagged by the user
  has_many    :asset_tags
  has_many    :users, :through => :asset_tags

  # Validations on associations
  validates     :organization_id,     :presence => true
  validates     :asset_type_id,       :presence => true
  validates     :asset_subtype_id,    :presence => true
  validates     :created_by_id,       :presence => true
  validates     :manufacture_year,    :presence => true, :numericality => {:only_integer => :true, :greater_than_or_equal_to => 1900}
  validates     :expected_useful_life, :numericality => {:only_integer => :true, :greater_than_or_equal_to => 0}, :presence => true
  validates_inclusion_of :purchased_new, :in => [true, false]
  validates     :purchase_cost,       :presence => :true, :numericality => {:only_integer => :true, :greater_than_or_equal_to => 0}
  validates     :purchase_date,       :presence => :true
  validates     :serial_number,       uniqueness: {scope: :organization, message: "must be unique within an organization"}, allow_nil: true, allow_blank: true

  #validates     :in_service_date,     :presence => :true

  #-----------------------------------------------------------------------------
  # Attributes common to all asset types
  #-----------------------------------------------------------------------------
<commit_msg>[#115036823] in service date required for transit assets only<commit_after>#-------------------------------------------------------------------------------
#
# Asset
#
# Base class for all assets. This class represents a generic asset, subclasses represent concrete
# asset types.
#
#-------------------------------------------------------------------------------
class Asset < ActiveRecord::Base

  OBJECT_CACHE_EXPIRE_SECONDS = Rails.application.config.object_cache_expire_seconds
  # The policy analyzer to use comes from the Rails config
  POLICY_ANALYZER = Rails.application.config.policy_analyzer

  #-----------------------------------------------------------------------------
  # Behaviors
  #-----------------------------------------------------------------------------
  include TransamObjectKey
  include TransamNumericSanitizers
  include FiscalYear

  #-----------------------------------------------------------------------------
  # Callbacks
  #-----------------------------------------------------------------------------
  after_initialize  :set_defaults

  # Clean up any HABTM associations before the asset is destroyed
  before_destroy { asset_groups.clear }

  # Before the asset is updated we may need to update things like estimated
  # replacement cost if they updated other things
  before_update   :before_update_callback, :except => :create

  before_update :clear_cache

  #-----------------------------------------------------------------------------
  # Associations common to all asset types
  #-----------------------------------------------------------------------------

  # each asset belongs to a single organization
  belongs_to  :organization

  # each asset has a single asset type
  belongs_to  :asset_type

  # each asset has a single asset subtype
  belongs_to  :asset_subtype

  # each asset has a single maintenance provider type
  belongs_to  :maintenance_provider_type

  # each asset has a reason why it is being replaced
  belongs_to  :replacement_reason_type

  # each was puchased from a vendor
  belongs_to  :vendor

  # each belongs to a single manufacturer
  belongs_to  :manufacturer

  # each can belong to a parent
  belongs_to  :parent, :class_name => "Asset",  :foreign_key => :parent_id

  # Each asset has zero or more asset events. These are all events regardless of
  # event type. Events are deleted when the asset is deleted
  has_many   :asset_events, :dependent => :destroy

  # each asset has zero or more condition updates
  has_many   :condition_updates, -> {where :asset_event_type_id => ConditionUpdateEvent.asset_event_type.id }, :class_name => "ConditionUpdateEvent"

  # each asset has zero or more scheduled replacement updates
  has_many   :schedule_replacement_updates, -> {where :asset_event_type_id => ScheduleReplacementUpdateEvent.asset_event_type.id }, :class_name => "ScheduleReplacementUpdateEvent"

  # each asset has zero or more scheduled rehabilitation updates
  has_many   :schedule_rehabilitation_updates, -> {where :asset_event_type_id => ScheduleRehabilitationUpdateEvent.asset_event_type.id }, :class_name => "ScheduleRehabilitationUpdateEvent"

  # each asset has zero or more recorded rehabilitation events
  has_many   :rehabilitation_updates, -> {where :asset_event_type_id => RehabilitationUpdateEvent.asset_event_type.id}, :class_name => "RehabilitationUpdateEvent"

  # each asset has zero or more scheduled disposition updates
  has_many   :schedule_disposition_updates, -> {where :asset_event_type_id => ScheduleDispositionUpdateEvent.asset_event_type.id }, :class_name => "ScheduleDispositionUpdateEvent"

  # each asset has zero or more service status updates
  has_many   :service_status_updates, -> {where :asset_event_type_id => ServiceStatusUpdateEvent.asset_event_type.id }, :class_name => "ServiceStatusUpdateEvent"

  # each asset has zero or more disposition updates
  has_many   :disposition_updates, -> {where :asset_event_type_id => DispositionUpdateEvent.asset_event_type.id }, :class_name => "DispositionUpdateEvent"

  # each asset has zero or more early disposition requests
  has_many   :early_disposition_requests, -> {where :asset_event_type_id => EarlyDispositionRequestUpdateEvent.asset_event_type.id }, :class_name => "EarlyDispositionRequestUpdateEvent"

  # each asset has zero or more location updates.
  has_many   :location_updates, -> {where :asset_event_type_id => LocationUpdateEvent.asset_event_type.id }, :class_name => "LocationUpdateEvent"

  # Each asset has zero or more images. Images are deleted when the asset is deleted
  has_many    :images,      :as => :imagable,       :dependent => :destroy

  # Each asset has zero or more documents. Documents are deleted when the asset is deleted
  has_many    :documents,   :as => :documentable, :dependent => :destroy

  # Each asset has zero or more comments. Documents are deleted when the asset is deleted
  has_many    :comments,    :as => :commentable,  :dependent => :destroy

  # Each asset has zero or more tasks. Tasks are deleted when the asset is deleted
  has_many    :tasks,       :as => :taskable,     :dependent => :destroy

  # Each asset can have 0 or more dependents
  has_many    :dependents,  :class_name => 'Asset', :foreign_key => :parent_id, :dependent => :nullify

  # Each asset can be associated with 0 or more asset groups
  has_and_belongs_to_many :asset_groups

  # Each asset was created and updated by a user
  belongs_to :creator, :class_name => "User", :foreign_key => :created_by_id
  belongs_to :updator, :class_name => "User", :foreign_key => :updated_by_id

  # Has been tagged by the user
  has_many    :asset_tags
  has_many    :users, :through => :asset_tags

  # Validations on associations
  validates     :organization_id,     :presence => true
  validates     :asset_type_id,       :presence => true
  validates     :asset_subtype_id,    :presence => true
  validates     :created_by_id,       :presence => true
  validates     :manufacture_year,    :presence => true, :numericality => {:only_integer => :true, :greater_than_or_equal_to => 1900}
  validates     :expected_useful_life, :numericality => {:only_integer => :true, :greater_than_or_equal_to => 0}, :presence => true
  validates_inclusion_of :purchased_new, :in => [true, false]
  validates     :purchase_cost,       :presence => :true, :numericality => {:only_integer => :true, :greater_than_or_equal_to => 0}
  validates     :purchase_date,       :presence => :true
  validates     :serial_number,       uniqueness: {scope: :organization, message: "must be unique within an organization"}, allow_nil: true, allow_blank: true

  #-----------------------------------------------------------------------------
  # Attributes common to all asset types
  #-----------------------------------------------------------------------------

{'fraction_non_alphanumeric': 0.1821776378414, 'fraction_numerical': 0.0018305630812037782, 'mean_word_length': 2.612271885744512, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 134, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3783367', 'n_tokens_mistral': 3667, 'n_tokens_neox': 3503, 'n_words': 1128}