<commit_before>require 'sequel'
require 'money'

module Openbill
  class Service
    ACCOUNT_IDENT_DELIMETER = '/'

    Error = Class.new StandardError
    NoSuchAccount = Class.new Error
    NoSuchCategory = Class.new Error
    WrongCurrency = Class.new Error

    attr_reader :db, :config

    def initialize(config)
      @config = config
      @db = Sequel.connect config.database, logger: config.logger, max_connections: config.max_connections, reconnect: true
      @db.extension :pagination
      @db.extension :pg_hstore
    end

    def policies
      Openbill::Policy.dataset
    end

    def transactions
      Openbill::Transaction.dataset
    end

    def operations
      Openbill::Operation.dataset
    end

    def categories
      Openbill::Category.dataset
    end

    def notify_transaction(transaction)
      transaction_id = transaction.is_a?(Openbill::Transaction) ? transaction.id : transaction
      db.execute "notify #{TRANSACTIONS_TABLE_NAME}, '#{transaction_id}'"
    end

    def webhook_logs
      Openbill::WebhookLog.dataset
    end

    def goods
      Openbill::Good.dataset
    end

    def goods_availabilities
      Openbill::GoodAvailability.dataset
    end

    def good_units
      goods.select(:unit).distinct.order(Sequel.asc(:unit))
    end

    # Return accounts repositiory (actualy sequel dataset)
    #
    def accounts
      Openbill::Account.dataset
    end

    def get_category(id)
      Openbill::Category[id: id]
    end

    # @param ident - ident аккаунта в виде: [:category, :key]
    #
    # @param options - опции применяемые для создания аккаунта (см create_account)
    #
    def get_or_create_account_by_key(key, category_id:, currency: nil, details: nil, meta: {})
      account = get_account_by_key(key)
      currency ||= config.default_currency

      if account.present?
        # TODO: Do we need to update account details and meta?
        fail WrongCurrency, "Account currency is wrong #{account.amount_currency} <> #{currency}" unless account.amount_currency == currency
        return account
      else
        create_account key, category_id: category_id, currency: currency, details: details, meta: meta
      end
    end

    def get_account(account)
      case account
      when String
        get_account_by_id(account)
      when Symbol
        get_account_by_key(account)
      when Openbill::Account
        account
      else
        fail "Unknown type of account '#{account}' (#{account.class}). Must be Fixnum, Array or Openbill::Account"
      end
    end

    def get_account_by_id(id)
      Openbill::Account[id: id]
    end

    # @param key - key аккаунта
    def get_account_by_key(key)
      Openbill::Account[key: key.to_s]
    end

    def create_account(account_key, category_id:, id: nil, currency: nil, details: nil, meta: {})
      attrs = {
        category_id:     category_id,
        key:             account_key,
        details:         details,
        meta:            meta,
        amount_currency: currency || config.default_currency
      }
      unless id.nil?
        attrs[:id] = id
        Openbill::Account.unrestrict_primary_key
      end
      Openbill::Account.create(attrs)
    end

    def create_category(name, id: nil, parent_id: nil)
      attrs = { name: name, parent_id: parent_id }
      unless id.nil?
        attrs[:id] = id
        Openbill::Category.unrestrict_primary_key
      end
      Openbill::Category.create(attrs)
    end

    def account_transactions(ident)
      account = ident.is_a?(Openbill::Account) ? ident : get_account(ident)
      Openbill::Transaction
        .where('from_account_id = ? or to_account_id = ?', account.id, account.id)
    end

    # @param key - уникальный текстовый ключ транзакции
    #
    def make_transaction(from:, to:, amount:, key:, details: , meta: {})
      account_from = get_account from
      account_to = get_account to

      amount = prepare_amount amount, account_from.amount_currency

      Openbill::Transaction.create(
        from_account_id: account_from.id,
        to_account_id:   account_to.id,
        amount_cents:    amount.cents,
        amount_currency: amount.currency.iso_code,
        key:             key,
        details:         details,
        meta:            meta
      )
    end

    def get_transaction(id)
      Openbill::Transaction[id: id]
    end
<commit_msg>add date argument to make_transaction<commit_after>require 'sequel'
require 'money'

module Openbill
  class Service
    ACCOUNT_IDENT_DELIMETER = '/'

    Error = Class.new StandardError
    NoSuchAccount = Class.new Error
    NoSuchCategory = Class.new Error
    WrongCurrency = Class.new Error

    attr_reader :db, :config

    def initialize(config)
      @config = config
      @db = Sequel.connect config.database, logger: config.logger, max_connections: config.max_connections, reconnect: true
      @db.extension :pagination
      @db.extension :pg_hstore
    end

    def policies
      Openbill::Policy.dataset
    end

    def transactions
      Openbill::Transaction.dataset
    end

    def operations
      Openbill::Operation.dataset
    end

    def categories
      Openbill::Category.dataset
    end

    def notify_transaction(transaction)
      transaction_id = transaction.is_a?(Openbill::Transaction) ? transaction.id : transaction
      db.execute "notify #{TRANSACTIONS_TABLE_NAME}, '#{transaction_id}'"
    end

    def webhook_logs
      Openbill::WebhookLog.dataset
    end

    def goods
      Openbill::Good.dataset
    end

    def goods_availabilities
      Openbill::GoodAvailability.dataset
    end

    def good_units
      goods.select(:unit).distinct.order(Sequel.asc(:unit))
    end

    # Return accounts repositiory (actualy sequel dataset)
    #
    def accounts
      Openbill::Account.dataset
    end

    def get_category(id)
      Openbill::Category[id: id]
    end

    # @param ident - ident аккаунта в виде: [:category, :key]
    #
    # @param options - опции применяемые для создания аккаунта (см create_account)
    #
    def get_or_create_account_by_key(key, category_id:, currency: nil, details: nil, meta: {})
      account = get_account_by_key(key)
      currency ||= config.default_currency

      if account.present?
        # TODO: Do we need to update account details and meta?
        fail WrongCurrency, "Account currency is wrong #{account.amount_currency} <> #{currency}" unless account.amount_currency == currency
        return account
      else
        create_account key, category_id: category_id, currency: currency, details: details, meta: meta
      end
    end

    def get_account(account)
      case account
      when String
        get_account_by_id(account)
      when Symbol
        get_account_by_key(account)
      when Openbill::Account
        account
      else
        fail "Unknown type of account '#{account}' (#{account.class}). Must be Fixnum, Array or Openbill::Account"
      end
    end

    def get_account_by_id(id)
      Openbill::Account[id: id]
    end

    # @param key - key аккаунта
    def get_account_by_key(key)
      Openbill::Account[key: key.to_s]
    end

    def create_account(account_key, category_id:, id: nil, currency: nil, details: nil, meta: {})
      attrs = {
        category_id:     category_id,
        key:             account_key,
        details:         details,
        meta:            meta,
        amount_currency: currency || config.default_currency
      }
      unless id.nil?
        attrs[:id] = id
        Openbill::Account.unrestrict_primary_key
      end
      Openbill::Account.create(attrs)
    end

    def create_category(name, id: nil, parent_id: nil)
      attrs = { name: name, parent_id: parent_id }
      unless id.nil?
        attrs[:id] = id
        Openbill::Category.unrestrict_primary_key
      end
      Openbill::Category.create(attrs)
    end

    def account_transactions(ident)
      account = ident.is_a?(Openbill::Account) ? ident : get_account(ident)
      Openbill::Transaction
        .where('from_account_id = ? or to_account_id = ?', account.id, account.id)
    end

    # @param key - уникальный текстовый ключ транзакции
    #
    def make_transaction(from:, to:, amount:, key:, details: , date: nil, meta: {})
      account_from = get_account from
      account_to = get_account to

      amount = prepare_amount amount, account_from.amount_currency

      Openbill::Transaction.create(
        from_account_id: account_from.id,
        to_account_id:   account_to.id,
        amount_cents:    amount.cents,
        amount_currency: amount.currency.iso_code,
        date:            date,
        key:             key,
        details:         details,
        meta:            meta
      )
    end

    def get_transaction(id)
      Openbill::Transaction[id: id]
    end

{'fraction_non_alphanumeric': 0.08492279745685741, 'fraction_numerical': 0.0, 'mean_word_length': 2.5462962962962963, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '4002689', 'n_tokens_mistral': 2684, 'n_tokens_neox': 2591, 'n_words': 640}