<commit_before># = Informations
#
# == License
#
# Ekylibre - Simple agricultural ERP
# Copyright (C) 2008-2009 <NAME>, <NAME>
# Copyright (C) 2010-2012 <NAME>
# Copyright (C) 2012-2018 <NAME>, <NAME>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see http://www.gnu.org/licenses.
#
# == Table: entities
#
#  active                       :boolean          default(TRUE), not null
#  activity_code                :string
#  authorized_payments_count    :integer
#  bank_account_holder_name     :string
#  bank_identifier_code         :string
#  born_at                      :datetime
#  client                       :boolean          default(FALSE), not null
#  client_account_id            :integer
#  codes                        :jsonb
#  country                      :string
#  created_at                   :datetime         not null
#  creator_id                   :integer
#  currency                     :string           not null
#  custom_fields                :jsonb
#  dead_at                      :datetime
#  deliveries_conditions        :string
#  description                  :text
#  employee                     :boolean          default(FALSE), not null
#  employee_account_id          :integer
#  first_financial_year_ends_on :date
#  first_met_at                 :datetime
#  first_name                   :string
#  full_name                    :string           not null
#  iban                         :string
#  id                           :integer          not null, primary key
#  language                     :string           not null
#  last_name                    :string           not null
#  lock_version                 :integer          default(0), not null
#  locked                       :boolean          default(FALSE), not null
#  meeting_origin               :string
#  nature                       :string           not null
#  number                       :string
#  of_company                   :boolean          default(FALSE), not null
#  picture_content_type         :string
#  picture_file_name            :string
#  picture_file_size            :integer
#  picture_updated_at           :datetime
#  proposer_id                  :integer
#  prospect                     :boolean          default(FALSE), not null
#  reminder_submissive          :boolean          default(FALSE), not null
#  responsible_id               :integer
#  siret_number                 :string
#  supplier                     :boolean          default(FALSE), not null
#  supplier_account_id          :integer
#  supplier_payment_delay       :string
#  supplier_payment_mode_id     :integer
#  title                        :string
#  transporter                  :boolean          default(FALSE), not null
#  updated_at                   :datetime         not null
#  updater_id                   :integer
#  vat_number                   :string
#  vat_subjected                :boolean          default(TRUE), not null
#

require 'digest/sha2'

class Entity < Ekylibre::Record::Base
  include Attachable
  include Commentable
  include Versionable
  include Customizable
  attr_accessor :password_confirmation, :old_password
  refers_to :currency
  refers_to :language
  refers_to :country
  enumerize :nature, in: %i[organization contact], default: :organization, predicates: true
  versionize exclude: [:full_name]
  belongs_to :client_account, class_name: 'Account'
  belongs_to :employee_account, class_name: 'Account'
  # belongs_to :payment_mode, class_name: "IncomingPaymentMode"
  belongs_to :proposer, class_name: 'Entity'
  belongs_to :responsible, class_name: 'User'
  belongs_to :supplier_account, class_name: 'Account'
  belongs_to :supplier_payment_mode, class_name: 'OutgoingPaymentMode'
  has_many :clients, class_name: 'Entity', foreign_key: :responsible_id, dependent: :nullify
  with_options class_name: 'EntityAddress', inverse_of: :entity, dependent: :destroy do
    has_many :all_addresses
    has_many :addresses, -> { actives }
    has_many :mails,     -> { actives.mails    }
    has_many :emails,    -> { actives.emails   }
    has_many :phones,    -> { actives.phones   }
    has_many :mobiles,   -> { actives.mobiles  }
    has_many :faxes,     -> { actives.faxes    }
    has_many :websites,  -> { actives.websites }
    has_many :auto_updateable_addresses, -> { actives.where(mail_auto_update: true) }
  end
  has_many :contracts, foreign_key: :supplier_id, dependent: :restrict_with_exception
  has_many :direct_links, class_name: 'EntityLink', foreign_key: :entity_id, dependent: :destroy
  has_many :events, through: :participations
  has_many :gaps, dependent: :restrict_with_error
  has_many :issues, as: :target, dependent: :destroy
  has_many :godchildren, class_name: 'Entity', foreign_key: 'proposer_id'
  has_many :incoming_payments, foreign_key: :payer_id, inverse_of: :payer
  has_many :indirect_links, class_name: 'EntityLink', foreign_key: :linked_id, dependent: :destroy
  has_many :purchase_payments, foreign_key: :payee_id
  has_many :ownerships, class_name: 'ProductOwnership', foreign_key: :owner_id
  has_many :participations, class_name: 'EventParticipation', foreign_key: :participant_id, dependent: :destroy
  has_many :purchase_invoices, -> { where(state: 'invoice').order(created_at: :desc) },
           class_name: 'Purchase', foreign_key: :supplier_id
  has_many :purchases, foreign_key: :supplier_id, dependent: :restrict_with_exception
  has_many :purchase_items, through: :purchases, source: :items
  has_many :parcels, foreign_key: :transporter_id
  has_many :incoming_parcels, class_name: 'Parcel', foreign_key: :sender_id
  has_many :outgoing_parcels, class_name: 'Parcel', foreign_key: :recipient_id
  has_many :sales_invoices, -> { where(state: 'invoice').order(created_at: :desc) },
           class_name: 'Sale', foreign_key: :client_id
  has_many :sales, -> { order(created_at: :desc) }, foreign_key: :client_id, dependent: :restrict_with_exception
  has_many :sale_opportunities, -> { order(created_at: :desc) }, foreign_key: :third_id, dependent: :destroy
  has_many :managed_sales, -> { order(created_at: :desc) }, foreign_key: :responsible_id, class_name: 'Sale'
  has_many :sale_items, through: :sales, source: :items
  has_many :subscriptions, foreign_key: :subscriber_id, dependent: :restrict_with_error
  has_many :tasks
  has_many :trackings, foreign_key: :producer_id
  has_many :deliveries, foreign_key: :transporter_id, dependent: :restrict_with_error
  has_many :transporter_sales, -> { order(created_at: :desc) }, foreign_key: :transporter_id, class_name: 'Sale'
  has_many :waiting_deliveries, -> { where(state: 'ready_to_send') }, class_name: 'Parcel', foreign_key: :transporter_id
  has_many :booked_journals, class_name: 'Journal', foreign_key: :accountant_id
  has_many :financial_years, class_name: 'FinancialYear', foreign_key: :accountant_id
  has_many :purchase_affairs, -> { order(created_at: :desc) }, foreign_key: :third_id, dependent: :destroy
  has_many :client_journal_entry_items, through: :client_account, source: :journal_entry_items
  has_many :supplier_journal_entry_items, through: :supplier_account, source: :journal_entry_items

  with_options class_name: 'EntityAddress' do
    has_one :default_mail_address, -> { where(by_default: true, canal: 'mail') }
    has_one :default_email_address, -> { where(by_default: true, canal: 'email') }
    has_one :default_phone_address, -> { where(by_default: true, canal: 'phone') }
    has_one :default_mobile_address, -> { where(by_default: true, canal: 'mobile') }
    has_one :default_fax_address, -> { where(by_default: true, canal: 'fax') }
    has_one :default_website_address, -> { where(by_default: true, canal: 'website') }
  end
  has_one :economic_situation, foreign_key: :id
  has_one :cash, class_name: 'Cash', foreign_key: :owner_id
  has_one :worker, foreign_key: :person_id
  has_one :user, foreign_key: :person_id
  has_picture

  # [VALIDATORS[ Do not edit these lines directly. Use `rake clean:validations`.
  validates :active, :client, :employee, :locked, :of_company, :prospect, :reminder_submissive, :supplier, :transporter, :vat_subjected, inclusion: { in: [true, false] }
  validates :activity_code, :bank_account_holder_name, :bank_identifier_code, :deliveries_conditions, :first_name, :iban, :meeting_origin, :number, :picture_content_type, :picture_file_name, :siret_number, :supplier_payment_delay, :title, :vat_number, length: { maximum: 500 }, allow_blank: true
  validates :born_at, :dead_at, :first_met_at, :picture_updated_at, timeliness: { on_or_after: -> { Time.new(1, 1, 1).in_time_zone }, on_or_before: -> { Time.zone.now + 50.years } }, allow_blank: true
  validates :currency, :language, :nature, presence: true
  validates :description, length: { maximum: 500_000 }, allow_blank: true
  validates :first_financial_year_ends_on, timeliness: { on_or_after: -> { Time.new(1, 1, 1).in_time_zone }, on_or_before: -> { Time.zone.now + 50.years }, type: :date }, allow_blank: true
  validates :full_name, :last_name, presence: true, length: { maximum: 500 }
  validates :picture_file_size, numericality: { only_integer: true, greater_than: -2_147_483_649, less_than: 2_147_483_648 }, allow_blank: true
  # ]VALIDATORS]
  validates :country, length: { allow_nil: true, maximum: 2 }
  validates :language, length: { allow_nil: true, maximum: 3 }
  validates :siret_number, length: { allow_nil: true, maximum: 14 }
  validates :vat_number, length: { allow_nil: true, maximum: 20 }
  validates :activity_code, length: { allow_nil: true, maximum: 30 }
  validates :deliveries_conditions, :number, length: { allow_nil: true, maximum: 60 }
  validates :iban, iban: true, allow_blank: true
  validates :siret_number, siret_format: true, allow_blank: true
  validates_attachment_content_type :picture, content_type: /image/
  validates_delay_format_of :supplier_payment_delay

  alias_attribute :name, :full_name

  scope :normal, -> { where(of_company: false) }
  scope :necessary_transporters, -> { where("transporter OR id IN (SELECT transporter_id FROM #{Parcel.table_name} WHERE state != 'sent' OR delivery_id IS NULL)").order(:last_name, :first_name) }
  scope :suppliers,    -> { where(supplier: true) }
  scope :transporters, -> { where(transporter: true) }
  scope :clients,      -> { where(client: true) }
  scope :employees,    -> { where(employee: true) }
  scope :company,      -> { where(of_company: true) }
  scope :related_to, lambda { |entity|
    where("id IN (SELECT linked_id FROM #{EntityLink.table_name} WHERE entity_id = ?) OR id IN (SELECT entity_id FROM #{EntityLink.table_name} WHERE linked_id = ?)", entity.id, entity.id)
  }
  scope :users, -> { where(id: User.select(:person_id)) }
  scope :responsibles,  -> { contacts }
  scope :contacts,      -> { where(nature: 'contact') }
  scope :organizations, -> { where(nature: 'organization') }
  scope :with_address, ->(canal, coordinate) {
    where(id: EntityAddress.where(canal: canal, coordinate: coordinate).select(:entity_id))
  }
  scope :with_email, ->(email) { with_address(:email, email) }

  acts_as_numbered :number, force: false, readonly: false<commit_msg>Don't validate siret if company is not french<commit_after># = Informations
#
# == License
#
# Ekylibre - Simple agricultural ERP
# Copyright (C) 2008-2009 <NAME>, <NAME>
# Copyright (C) 2010-2012 <NAME>
# Copyright (C) 2012-2018 <NAME>, <NAME>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see http://www.gnu.org/licenses.
#
# == Table: entities
#
#  active                       :boolean          default(TRUE), not null
#  activity_code                :string
#  authorized_payments_count    :integer
#  bank_account_holder_name     :string
#  bank_identifier_code         :string
#  born_at                      :datetime
#  client                       :boolean          default(FALSE), not null
#  client_account_id            :integer
#  codes                        :jsonb
#  country                      :string
#  created_at                   :datetime         not null
#  creator_id                   :integer
#  currency                     :string           not null
#  custom_fields                :jsonb
#  dead_at                      :datetime
#  deliveries_conditions        :string
#  description                  :text
#  employee                     :boolean          default(FALSE), not null
#  employee_account_id          :integer
#  first_financial_year_ends_on :date
#  first_met_at                 :datetime
#  first_name                   :string
#  full_name                    :string           not null
#  iban                         :string
#  id                           :integer          not null, primary key
#  language                     :string           not null
#  last_name                    :string           not null
#  lock_version                 :integer          default(0), not null
#  locked                       :boolean          default(FALSE), not null
#  meeting_origin               :string
#  nature                       :string           not null
#  number                       :string
#  of_company                   :boolean          default(FALSE), not null
#  picture_content_type         :string
#  picture_file_name            :string
#  picture_file_size            :integer
#  picture_updated_at           :datetime
#  proposer_id                  :integer
#  prospect                     :boolean          default(FALSE), not null
#  reminder_submissive          :boolean          default(FALSE), not null
#  responsible_id               :integer
#  siret_number                 :string
#  supplier                     :boolean          default(FALSE), not null
#  supplier_account_id          :integer
#  supplier_payment_delay       :string
#  supplier_payment_mode_id     :integer
#  title                        :string
#  transporter                  :boolean          default(FALSE), not null
#  updated_at                   :datetime         not null
#  updater_id                   :integer
#  vat_number                   :string
#  vat_subjected                :boolean          default(TRUE), not null
#

require 'digest/sha2'

class Entity < Ekylibre::Record::Base
  include Attachable
  include Commentable
  include Versionable
  include Customizable
  attr_accessor :password_confirmation, :old_password
  refers_to :currency
  refers_to :language
  refers_to :country
  enumerize :nature, in: %i[organization contact], default: :organization, predicates: true
  versionize exclude: [:full_name]
  belongs_to :client_account, class_name: 'Account'
  belongs_to :employee_account, class_name: 'Account'
  # belongs_to :payment_mode, class_name: "IncomingPaymentMode"
  belongs_to :proposer, class_name: 'Entity'
  belongs_to :responsible, class_name: 'User'
  belongs_to :supplier_account, class_name: 'Account'
  belongs_to :supplier_payment_mode, class_name: 'OutgoingPaymentMode'
  has_many :clients, class_name: 'Entity', foreign_key: :responsible_id, dependent: :nullify
  with_options class_name: 'EntityAddress', inverse_of: :entity, dependent: :destroy do
    has_many :all_addresses
    has_many :addresses, -> { actives }
    has_many :mails,     -> { actives.mails    }
    has_many :emails,    -> { actives.emails   }
    has_many :phones,    -> { actives.phones   }
    has_many :mobiles,   -> { actives.mobiles  }
    has_many :faxes,     -> { actives.faxes    }
    has_many :websites,  -> { actives.websites }
    has_many :auto_updateable_addresses, -> { actives.where(mail_auto_update: true) }
  end
  has_many :contracts, foreign_key: :supplier_id, dependent: :restrict_with_exception
  has_many :direct_links, class_name: 'EntityLink', foreign_key: :entity_id, dependent: :destroy
  has_many :events, through: :participations
  has_many :gaps, dependent: :restrict_with_error
  has_many :issues, as: :target, dependent: :destroy
  has_many :godchildren, class_name: 'Entity', foreign_key: 'proposer_id'
  has_many :incoming_payments, foreign_key: :payer_id, inverse_of: :payer
  has_many :indirect_links, class_name: 'EntityLink', foreign_key: :linked_id, dependent: :destroy
  has_many :purchase_payments, foreign_key: :payee_id
  has_many :ownerships, class_name: 'ProductOwnership', foreign_key: :owner_id
  has_many :participations, class_name: 'EventParticipation', foreign_key: :participant_id, dependent: :destroy
  has_many :purchase_invoices, -> { where(state: 'invoice').order(created_at: :desc) },
           class_name: 'Purchase', foreign_key: :supplier_id
  has_many :purchases, foreign_key: :supplier_id, dependent: :restrict_with_exception
  has_many :purchase_items, through: :purchases, source: :items
  has_many :parcels, foreign_key: :transporter_id
  has_many :incoming_parcels, class_name: 'Parcel', foreign_key: :sender_id
  has_many :outgoing_parcels, class_name: 'Parcel', foreign_key: :recipient_id
  has_many :sales_invoices, -> { where(state: 'invoice').order(created_at: :desc) },
           class_name: 'Sale', foreign_key: :client_id
  has_many :sales, -> { order(created_at: :desc) }, foreign_key: :client_id, dependent: :restrict_with_exception
  has_many :sale_opportunities, -> { order(created_at: :desc) }, foreign_key: :third_id, dependent: :destroy
  has_many :managed_sales, -> { order(created_at: :desc) }, foreign_key: :responsible_id, class_name: 'Sale'
  has_many :sale_items, through: :sales, source: :items
  has_many :subscriptions, foreign_key: :subscriber_id, dependent: :restrict_with_error
  has_many :tasks
  has_many :trackings, foreign_key: :producer_id
  has_many :deliveries, foreign_key: :transporter_id, dependent: :restrict_with_error
  has_many :transporter_sales, -> { order(created_at: :desc) }, foreign_key: :transporter_id, class_name: 'Sale'
  has_many :waiting_deliveries, -> { where(state: 'ready_to_send') }, class_name: 'Parcel', foreign_key: :transporter_id
  has_many :booked_journals, class_name: 'Journal', foreign_key: :accountant_id
  has_many :financial_years, class_name: 'FinancialYear', foreign_key: :accountant_id
  has_many :purchase_affairs, -> { order(created_at: :desc) }, foreign_key: :third_id, dependent: :destroy
  has_many :client_journal_entry_items, through: :client_account, source: :journal_entry_items
  has_many :supplier_journal_entry_items, through: :supplier_account, source: :journal_entry_items

  with_options class_name: 'EntityAddress' do
    has_one :default_mail_address, -> { where(by_default: true, canal: 'mail') }
    has_one :default_email_address, -> { where(by_default: true, canal: 'email') }
    has_one :default_phone_address, -> { where(by_default: true, canal: 'phone') }
    has_one :default_mobile_address, -> { where(by_default: true, canal: 'mobile') }
    has_one :default_fax_address, -> { where(by_default: true, canal: 'fax') }
    has_one :default_website_address, -> { where(by_default: true, canal: 'website') }
  end
  has_one :economic_situation, foreign_key: :id
  has_one :cash, class_name: 'Cash', foreign_key: :owner_id
  has_one :worker, foreign_key: :person_id
  has_one :user, foreign_key: :person_id
  has_picture

  # [VALIDATORS[ Do not edit these lines directly. Use `rake clean:validations`.
  validates :active, :client, :employee, :locked, :of_company, :prospect, :reminder_submissive, :supplier, :transporter, :vat_subjected, inclusion: { in: [true, false] }
  validates :activity_code, :bank_account_holder_name, :bank_identifier_code, :deliveries_conditions, :first_name, :iban, :meeting_origin, :number, :picture_content_type, :picture_file_name, :siret_number, :supplier_payment_delay, :title, :vat_number, length: { maximum: 500 }, allow_blank: true
  validates :born_at, :dead_at, :first_met_at, :picture_updated_at, timeliness: { on_or_after: -> { Time.new(1, 1, 1).in_time_zone }, on_or_before: -> { Time.zone.now + 50.years } }, allow_blank: true
  validates :currency, :language, :nature, presence: true
  validates :description, length: { maximum: 500_000 }, allow_blank: true
  validates :first_financial_year_ends_on, timeliness: { on_or_after: -> { Time.new(1, 1, 1).in_time_zone }, on_or_before: -> { Time.zone.now + 50.years }, type: :date }, allow_blank: true
  validates :full_name, :last_name, presence: true, length: { maximum: 500 }
  validates :picture_file_size, numericality: { only_integer: true, greater_than: -2_147_483_649, less_than: 2_147_483_648 }, allow_blank: true
  # ]VALIDATORS]
  validates :country, length: { allow_nil: true, maximum: 2 }
  validates :language, length: { allow_nil: true, maximum: 3 }
  validates :siret_number, length: { allow_nil: true, maximum: 14 }
  validates :vat_number, length: { allow_nil: true, maximum: 20 }
  validates :activity_code, length: { allow_nil: true, maximum: 30 }
  validates :deliveries_conditions, :number, length: { allow_nil: true, maximum: 60 }
  validates :iban, iban: true, allow_blank: true
  validates :siret_number, siret_format: {if: country == 'fr'}, allow_blank: true
  validates_attachment_content_type :picture, content_type: /image/
  validates_delay_format_of :supplier_payment_delay

  alias_attribute :name, :full_name

  scope :normal, -> { where(of_company: false) }
  scope :necessary_transporters, -> { where("transporter OR id IN (SELECT transporter_id FROM #{Parcel.table_name} WHERE state != 'sent' OR delivery_id IS NULL)").order(:last_name, :first_name) }
  scope :suppliers,    -> { where(supplier: true) }
  scope :transporters, -> { where(transporter: true) }
  scope :clients,      -> { where(client: true) }
  scope :employees,    -> { where(employee: true) }
  scope :company,      -> { where(of_company: true) }
  scope :related_to, lambda { |entity|
    where("id IN (SELECT linked_id FROM #{EntityLink.table_name} WHERE entity_id = ?) OR id IN (SELECT entity_id FROM #{EntityLink.table_name} WHERE linked_id = ?)", entity.id, entity.id)
  }
  scope :users, -> { where(id: User.select(:person_id)) }
  scope :responsibles,  -> { contacts }
  scope :contacts,      -> { where(nature: 'contact') }
  scope :organizations, -> { where(nature: 'organization') }
  scope :with_address, ->(canal, coordinate) {
    where(id: EntityAddress.where(canal: canal, coordinate: coordinate).select(:entity_id))
  }
  scope :with_email, ->(email) { with_address(:email, email) }

  acts_as_numbered :number, force: false, readonly: false
{'fraction_non_alphanumeric': 0.1035880370322966, 'fraction_numerical': 0.0067409019156107345, 'mean_word_length': 3.448661985196432, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '6112702', 'n_tokens_mistral': 7485, 'n_tokens_neox': 7190, 'n_words': 1852}