<commit_before>class InventoryBookkeeper < Ekylibre::Bookkeeper
  class NegativeStockValueError < StandardError
    attr_reader :account, :start, :stop, :amount

    def initialize(account, start, stop, amount)
      @account = account
      @start = start
      @stop = stop
      @amount = amount
    end

    def message
      "Found negative stock value (#{amount.to_f}) in account #{account.name} for the period #{start} - #{stop}"
    end
  end

  #          Mode Inventory     |     Debit                      |            Credit            |
  #     physical inventory      |    stock(3X)                   |   stock_movement(603X/71X)   |
  def call
    journal = ensure_journal_present

    journal_entry(journal, printed_on: achieved_at.to_date, if: (financial_year && reflected?)) do |entry|
      if journal.entries.any?
        first_started_at = journal.entries.reorder(:printed_on).first.printed_on.to_time
      end
      fy_started_at = first_started_at || financial_year.started_on.to_time

      # get all variants corresponding to current items
      item_variants.each do |variant|
        # for all items of current variant (if storable)
        # TODO: Put this as constraint in `inventory_variants`
        next unless variant.storable? && variant.stock_account && variant.stock_movement_account

        s = variant.stock_account
        sm = variant.stock_movement_account

        # get balance value of stock account for current fy (from fy started to inventory achieved at)
        current_stock_amount = s.journal_entry_items_calculate(:balance, fy_started_at, achieved_at)
        raise NegativeStockValueError.new(s, fy_started_at, achieved_at, current_stock_amount) if current_stock_amount < 0

        # step 2 : record inventory stock in stock journal
        # TODO update methods to evaluates price stock or open unit_pretax-
        # stock_amount field to the user during inventory
        # build the global value of the stock for each item
        inventoried_stock_amount = items.of_variant(variant).map(&:actual_pretax_stock_amount).compact.sum

        # bookkeep step 2
        # if current_stock_amount.zero?
        stock_movement_amount = inventoried_stock_amount - current_stock_amount

        label = tc(:bookkeep, resource: Inventory.model_name.human, number: number)
        entry.add_credit(label, sm.id, stock_movement_amount, resource: variant, as: :stock, variant: variant)
        entry.add_debit(label, s.id, stock_movement_amount, resource: variant, as: :stock_movement, variant: variant)
      end
    end
  end

  private

    def ensure_journal_present
      Journal.find_or_create_by!(name: :stocks.tl, nature: :various, used_for_permanent_stock_inventory: true)
    end
end<commit_msg>Make sure that calls to Journal::find_or_create_by! only require nature or meaningful keys<commit_after>class InventoryBookkeeper < Ekylibre::Bookkeeper
  class NegativeStockValueError < StandardError
    attr_reader :account, :start, :stop, :amount

    def initialize(account, start, stop, amount)
      @account = account
      @start = start
      @stop = stop
      @amount = amount
    end

    def message
      "Found negative stock value (#{amount.to_f}) in account #{account.name} for the period #{start} - #{stop}"
    end
  end

  #          Mode Inventory     |     Debit                      |            Credit            |
  #     physical inventory      |    stock(3X)                   |   stock_movement(603X/71X)   |
  def call
    journal = ensure_journal_present

    journal_entry(journal, printed_on: achieved_at.to_date, if: (financial_year && reflected?)) do |entry|
      if journal.entries.any?
        first_started_at = journal.entries.reorder(:printed_on).first.printed_on.to_time
      end
      fy_started_at = first_started_at || financial_year.started_on.to_time

      # get all variants corresponding to current items
      item_variants.each do |variant|
        # for all items of current variant (if storable)
        # TODO: Put this as constraint in `inventory_variants`
        next unless variant.storable? && variant.stock_account && variant.stock_movement_account

        s = variant.stock_account
        sm = variant.stock_movement_account

        # get balance value of stock account for current fy (from fy started to inventory achieved at)
        current_stock_amount = s.journal_entry_items_calculate(:balance, fy_started_at, achieved_at)
        raise NegativeStockValueError.new(s, fy_started_at, achieved_at, current_stock_amount) if current_stock_amount < 0

        # step 2 : record inventory stock in stock journal
        # TODO update methods to evaluates price stock or open unit_pretax-
        # stock_amount field to the user during inventory
        # build the global value of the stock for each item
        inventoried_stock_amount = items.of_variant(variant).map(&:actual_pretax_stock_amount).compact.sum

        # bookkeep step 2
        # if current_stock_amount.zero?
        stock_movement_amount = inventoried_stock_amount - current_stock_amount

        label = tc(:bookkeep, resource: Inventory.model_name.human, number: number)
        entry.add_credit(label, sm.id, stock_movement_amount, resource: variant, as: :stock, variant: variant)
        entry.add_debit(label, s.id, stock_movement_amount, resource: variant, as: :stock_movement, variant: variant)
      end
    end
  end

  private

    def ensure_journal_present
      Journal.create_with(name: :stocks.tl)
        .find_or_create_by!(nature: :various, used_for_permanent_stock_inventory: true)
    end
end
{'fraction_non_alphanumeric': 0.07303571428571429, 'fraction_numerical': 0.0032142857142857142, 'mean_word_length': 3.0323974082073435, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7382941', 'n_tokens_mistral': 1643, 'n_tokens_neox': 1563, 'n_words': 440}