<commit_before># = Informations
#
# == License
#
# Ekylibre - Simple agricultural ERP
# Copyright (C) 2008-2009 <NAME>, <NAME>
# Copyright (C) 2010-2012 <NAME>
# Copyright (C) 2012-2016 <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: parcel_items
#
#  analysis_id                   :integer
#  created_at                    :datetime         not null
#  creator_id                    :integer
#  id                            :integer          not null, primary key
#  lock_version                  :integer          default(0), not null
#  parcel_id                     :integer          not null
#  parted                        :boolean          default(FALSE), not null
#  population                    :decimal(19, 4)
#  product_enjoyment_id          :integer
#  product_id                    :integer
#  product_identification_number :string
#  product_localization_id       :integer
#  product_movement_id           :integer
#  product_name                  :string
#  product_ownership_id          :integer
#  purchase_item_id              :integer
#  sale_item_id                  :integer
#  shape                         :geometry({:srid=>4326, :type=>"multi_polygon"})
#  source_product_id             :integer
#  source_product_movement_id    :integer
#  updated_at                    :datetime         not null
#  updater_id                    :integer
#  variant_id                    :integer
#
class ParcelItem < Ekylibre::Record::Base
  attr_readonly :parcel_id
  attr_accessor :product_nature_variant_id
  belongs_to :analysis
  belongs_to :parcel, inverse_of: :items
  belongs_to :product
  belongs_to :product_enjoyment,          dependent: :destroy
  belongs_to :product_localization,       dependent: :destroy
  belongs_to :product_ownership,          dependent: :destroy
  belongs_to :product_movement,           dependent: :destroy
  belongs_to :purchase_item
  belongs_to :sale_item
  belongs_to :source_product, class_name: 'Product'
  belongs_to :source_product_movement, class_name: 'ProductMovement', dependent: :destroy
  belongs_to :variant, -> { of_variety :matter }, class_name: 'ProductNatureVariant'
  has_one :category, through: :variant
  has_one :nature, through: :variant
  has_one :delivery, through: :parcel
  has_one :storage, through: :parcel

  # [VALIDATORS[ Do not edit these lines directly. Use `rake clean:validations`.
  validates :parted, inclusion: { in: [true, false] }
  validates :population, numericality: { greater_than: -1_000_000_000_000_000, less_than: 1_000_000_000_000_000 }, allow_blank: true
  validates :product_identification_number, :product_name, length: { maximum: 500 }, allow_blank: true
  validates :parcel, presence: true
  # ]VALIDATORS]
  validates :source_product, presence: { if: :parcel_outgoing? }
  validates :variant, presence: { if: :parcel_incoming? }
  validates :product, presence: { if: :parcel_prepared? }

  validates :population, numericality: { less_than_or_equal_to: 1,
                                         if: :product_is_unitary?,
                                         message: 'activerecord.errors.messages.unitary_in_parcel'.t }
  validates :product_name, presence: { if: -> { product_is_identifiable? && parcel_incoming? } }
  validates :product_identification_number, presence: { if: -> { product_is_identifiable? && parcel_incoming? } }

  scope :with_nature, ->(nature) { joins(:parcel).merge(Parcel.with_nature(nature)) }

  alias_attribute :quantity, :population

  accepts_nested_attributes_for :product
  # delegate :net_mass, to: :product
  delegate :allow_items_update?, :remain_owner, :planned_at, :draft?,
           :ordered_at, :recipient, :in_preparation?, :in_preparation_at,
           :prepared?, :prepared_at, :given?, :given_at, :outgoing?, :incoming?,
           :separated_stock?, to: :parcel, prefix: true

  before_validation do
    read_at = parcel ? parcel_prepared_at : Time.zone.now
    self.population ||= product_is_unitary? ? 1 : 0
    next if parcel_incoming?

    if sale_item
      self.variant = sale_item.variant
    elsif purchase_item
      self.variant = purchase_item.variant
    elsif parcel_outgoing?
      self.variant = source_product.variant if source_product
    end
    true
  end

  ALLOWED = %w(
    product_localization_id
    product_movement_id
    product_enjoyment_id
    product_ownership_id
    purchase_item_id
    sale_item_id
    updated_at
  ).freeze
  protect(allow_update_on: ALLOWED, on: [:create, :destroy, :update]) do
    !parcel_allow_items_update?
  end<commit_msg>Added updater_id to the list of updateable attributes in #protected_on for ParcelItems. Fixes #1102.<commit_after># = Informations
#
# == License
#
# Ekylibre - Simple agricultural ERP
# Copyright (C) 2008-2009 <NAME>, <NAME>
# Copyright (C) 2010-2012 <NAME>
# Copyright (C) 2012-2016 <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: parcel_items
#
#  analysis_id                   :integer
#  created_at                    :datetime         not null
#  creator_id                    :integer
#  id                            :integer          not null, primary key
#  lock_version                  :integer          default(0), not null
#  parcel_id                     :integer          not null
#  parted                        :boolean          default(FALSE), not null
#  population                    :decimal(19, 4)
#  product_enjoyment_id          :integer
#  product_id                    :integer
#  product_identification_number :string
#  product_localization_id       :integer
#  product_movement_id           :integer
#  product_name                  :string
#  product_ownership_id          :integer
#  purchase_item_id              :integer
#  sale_item_id                  :integer
#  shape                         :geometry({:srid=>4326, :type=>"multi_polygon"})
#  source_product_id             :integer
#  source_product_movement_id    :integer
#  updated_at                    :datetime         not null
#  updater_id                    :integer
#  variant_id                    :integer
#
class ParcelItem < Ekylibre::Record::Base
  attr_readonly :parcel_id
  attr_accessor :product_nature_variant_id
  belongs_to :analysis
  belongs_to :parcel, inverse_of: :items
  belongs_to :product
  belongs_to :product_enjoyment,          dependent: :destroy
  belongs_to :product_localization,       dependent: :destroy
  belongs_to :product_ownership,          dependent: :destroy
  belongs_to :product_movement,           dependent: :destroy
  belongs_to :purchase_item
  belongs_to :sale_item
  belongs_to :source_product, class_name: 'Product'
  belongs_to :source_product_movement, class_name: 'ProductMovement', dependent: :destroy
  belongs_to :variant, -> { of_variety :matter }, class_name: 'ProductNatureVariant'
  has_one :category, through: :variant
  has_one :nature, through: :variant
  has_one :delivery, through: :parcel
  has_one :storage, through: :parcel

  # [VALIDATORS[ Do not edit these lines directly. Use `rake clean:validations`.
  validates :parted, inclusion: { in: [true, false] }
  validates :population, numericality: { greater_than: -1_000_000_000_000_000, less_than: 1_000_000_000_000_000 }, allow_blank: true
  validates :product_identification_number, :product_name, length: { maximum: 500 }, allow_blank: true
  validates :parcel, presence: true
  # ]VALIDATORS]
  validates :source_product, presence: { if: :parcel_outgoing? }
  validates :variant, presence: { if: :parcel_incoming? }
  validates :product, presence: { if: :parcel_prepared? }

  validates :population, numericality: { less_than_or_equal_to: 1,
                                         if: :product_is_unitary?,
                                         message: 'activerecord.errors.messages.unitary_in_parcel'.t }
  validates :product_name, presence: { if: -> { product_is_identifiable? && parcel_incoming? } }
  validates :product_identification_number, presence: { if: -> { product_is_identifiable? && parcel_incoming? } }

  scope :with_nature, ->(nature) { joins(:parcel).merge(Parcel.with_nature(nature)) }

  alias_attribute :quantity, :population

  accepts_nested_attributes_for :product
  # delegate :net_mass, to: :product
  delegate :allow_items_update?, :remain_owner, :planned_at, :draft?,
           :ordered_at, :recipient, :in_preparation?, :in_preparation_at,
           :prepared?, :prepared_at, :given?, :given_at, :outgoing?, :incoming?,
           :separated_stock?, to: :parcel, prefix: true

  before_validation do
    read_at = parcel ? parcel_prepared_at : Time.zone.now
    self.population ||= product_is_unitary? ? 1 : 0
    next if parcel_incoming?

    if sale_item
      self.variant = sale_item.variant
    elsif purchase_item
      self.variant = purchase_item.variant
    elsif parcel_outgoing?
      self.variant = source_product.variant if source_product
    end
    true
  end

  ALLOWED = %w(
    product_localization_id
    product_movement_id
    product_enjoyment_id
    product_ownership_id
    purchase_item_id
    sale_item_id
    updated_at
    updater_id
  ).freeze
  protect(allow_update_on: ALLOWED, on: [:create, :destroy, :update]) do
    !parcel_allow_items_update?
  end
{'fraction_non_alphanumeric': 0.08455034588777863, 'fraction_numerical': 0.014027671022290546, 'mean_word_length': 2.977455101260986, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '207057', 'n_tokens_mistral': 3247, 'n_tokens_neox': 3053, 'n_words': 831}