class Contabilidade::BloqueioDeDotacao < ApplicationRecord
	has_paper_trail
	include GeradorDeEventosContabeis
	include AASM
	attr_accessor :elemento_de_despesa_por_subacao_id, :subacao_id, :skip_validacao
	belongs_to :orcamento_da_despesa, class_name: 'Loa::OrcamentoDaDespesa'
	belongs_to :sub_elemento_de_despesa, class_name: 'Contabilidade::SubElementoDeDespesa'

	delegate :unidade_orcamentaria, to: :orcamento_da_despesa
	delegate :acao_codigo_e_nome, to: :orcamento_da_despesa
	delegate :fonte_de_recursos_codigo_e_descricao, to: :orcamento_da_despesa

	validates_presence_of :valor, :orcamento_da_despesa_id, :data_do_bloqueio

	validate :valor_nao_passar_do_saldo_da_dotacao, if: Proc.new { self.orcamento_da_despesa_id.present? && self.bloqueado? }

	enum status: {
		bloqueado: 1,
		desbloqueado: 2
	}

	aasm column: :status, enum: true, whiny_transitions: false do
		state :bloqueado, :initial => true
		state :desbloqueado

		event :desbloquear do
			transitions from: :bloqueado, to: :desbloqueado do
				after do
					self.update_column(:data_do_desbloqueio, Date.today)
				end
			end
		end
	end

	scope :ativos, -> { where(status: :bloqueado) }

	def valor_nao_passar_do_saldo_da_dotacao
		errors.add(:valor, "A dotação #{self.orcamento_da_despesa.try(:classificacao_completa)} possui saldo menor que o valor declarado") if self.valor.to_f > self.orcamento_da_despesa.saldo.to_f
	end

	after_destroy :apagar_movimento_orcamentario
	after_save :lancar_movimento_orcamentario

	def lancar_movimento_orcamentario
		if self.bloqueado?
			apagar_movimento_orcamentario
			movimentacao = Contabilidade::LancamentoDoOrcamentoDaDespesa.new(
				orcamento_da_despesa: self.orcamento_da_despesa,
				data_do_lancamento: self.data_do_bloqueio,
				valor: self.valor,
				modulo: self
			)
			movimentacao.save
		else
			movimentacao = Contabilidade::LancamentoDoOrcamentoDaDespesa.new(
				orcamento_da_despesa: self.orcamento_da_despesa,
				data_do_lancamento: Date.today,
				valor: -self.valor,
				modulo: self
			)
			movimentacao.save
		end
	end

	def apagar_movimento_orcamentario
		Contabilidade::LancamentoDoOrcamentoDaDespesa.find_by(modulo: self).try(:destroy)
	end
end
