require 'rails_helper'

RSpec.describe Contabilidade::Diaria, type: :model do
	cria_configuracao_default

	describe 'associations' do
		it { is_expected.to belong_to(:orcamento).required(true) }
		it { is_expected.to belong_to(:agente_publico_municipal).class_name('Base::AgentePublicoMunicipal').required(true) }
		it { is_expected.to belong_to(:unidade_orcamentaria).class_name('Loa::UnidadeOrcamentaria').required(true) }
		it { is_expected.to belong_to(:cidade).class_name('Base::Cidade').required(true) }
	end

	describe 'validations' do
		[:orcamento_id, :unidade_orcamentaria_id, :agente_publico_municipal_id,
		 :numero_da_portaria, :data_da_portaria, :cidade_id, :data_da_viagem,
		 :data_do_retorno, :valor, :historico].each do |atributo|
			it { is_expected.to validate_presence_of atributo }
		end

		it { is_expected.to validate_uniqueness_of( :numero ).scoped_to(:orcamento_id).case_insensitive}

		it { is_expected.to validate_length_of(:numero_da_portaria).is_at_most(13)}

		it { is_expected.to_not allow_value('').for(:data_da_portaria) }
		it { is_expected.to_not allow_value('00/').for(:data_da_portaria) }

		it { is_expected.to allow_value('01/01/2016').for(:data_da_viagem) }
		it { is_expected.to_not allow_value('').for(:data_da_viagem) }
		it { is_expected.to_not allow_value('00/').for(:data_da_viagem) }

		it { is_expected.to allow_value('01/01/2016').for(:data_do_retorno) }
		it { is_expected.to_not allow_value('').for(:data_do_retorno) }
		it { is_expected.to_not allow_value('00/').for(:data_do_retorno) }
	end

	describe 'valida data da portaria pelo exercício' do
		context 'quando a data da portaria é de um exercício diferente do orçamento' do
			before(:each) { @diaria = build(:diaria, data_da_portaria: Date.today) } #=> Orçamento de 2016

			it 'adiciona erro no campo data da portaria' do
				@diaria.save
				expect(@diaria.errors[:data_da_portaria]).to include('deve ser do mesmo exercício do orçamento')
			end

			it 'não permite criar a diária' do
				@diaria.save
				expect(@diaria.persisted?).to be false
				expect(Contabilidade::Diaria.count).to eql(0)
			end
		end

		context 'quando a data da portaria é do mesmo exercício do orçamento' do
			before(:each) { @diaria = build(:diaria, data_da_portaria: '2016-01-01') } #=> Orçamento de 2016

			it 'não adiciona erro no campo data da portaria' do
				@diaria.save
				expect(@diaria.errors[:data_da_portaria]).to be_empty
			end

			it 'permite criar a diária com sucesso' do
				@diaria.save
				expect(@diaria.persisted?).to be true
				expect(Contabilidade::Diaria.count).to eql(1)
			end
		end
	end

	describe '#dotacao_inclusa?' do
		context 'quando não há dotação na diária' do
			it 'retorna false' do
				diaria = create(:diaria, dotacao_na_diaria: false)
				expect(diaria.dotacao_inclusa?).to be false
			end
		end

		context 'quando há dotação na diária' do
			it 'retorna true' do
				diaria = create(:diaria, dotacao_na_diaria: true)
				create(:orcamento_da_despesa_por_diaria, diaria: diaria)
				expect(diaria.dotacao_inclusa?).to be true
			end
		end
	end

	describe '#valor_da_dotacao_igual_valor_da_diaria?' do
		context 'quando não há dotação na diária' do
			it 'retorna false' do
				diaria = create(:diaria, dotacao_na_diaria: false)
				expect(diaria.valor_da_dotacao_igual_valor_da_diaria?).to be false
			end
		end

		context 'quando há dotação na diária' do
			before(:each) { @diaria = create(:diaria, dotacao_na_diaria: true, valor: 500.00, qtd_de_diarias: 1) }

			context 'e o valor da dotação é diferente do valor total da diária' do
				it 'retorna false' do
					create(:orcamento_da_despesa_por_diaria, diaria: @diaria, valor: 499.99)
					expect(@diaria.valor_da_dotacao_igual_valor_da_diaria?).to be false
				end
			end

			context 'e o valor da dotação é igual ao valor total da diária' do
				it 'retorna true' do
					create(:orcamento_da_despesa_por_diaria, diaria: @diaria, valor: 500.00)
					expect(@diaria.valor_da_dotacao_igual_valor_da_diaria?).to be true
				end
			end
		end
	end

	describe '#pode_empenhar?' do
		context 'quando não há dotação na diária' do
			it 'retorna true' do
				diaria = create(:diaria, dotacao_na_diaria: false)
				expect(diaria.pode_empenhar?).to be true
			end
		end

		context 'quando há dotação na diária' do
			before(:each) { @diaria = create(:diaria, dotacao_na_diaria: true, valor: 100.00, qtd_de_diarias: 1) }

			context 'e o valor da dotação está diferente do total da diária' do
				it 'retorna false' do
					create(:orcamento_da_despesa_por_diaria, diaria: @diaria, valor: 99.99)
					expect(@diaria.pode_empenhar?).to be false
				end
			end

			context 'e o valor da dotação está igual ao total da diária' do
				it 'retorna true' do
					create(:orcamento_da_despesa_por_diaria, diaria: @diaria, valor: 100.00)
					expect(@diaria.pode_empenhar?).to be true
				end
			end
		end
	end

	describe '#empenho_gerado?' do
		before(:each) { @diaria = create(:diaria) }

		context 'quando a diária não possui empenho' do
			it 'retorna false' do
				expect(@diaria.empenho_gerado?).to be false
			end
		end

		context 'quando a diária possui empenho' do
			it 'retorna true' do
				create(:empenho_com_diaria, diaria: @diaria)
				expect(@diaria.empenho_gerado?).to be true
			end
		end
	end

	describe '#data_do_retorno_antes_da_data_da_viagem?' do
		context 'quando data do retorno é antes da data da viagem' do
			before(:each) { @diaria = build(:diaria, data_da_viagem: Date.today, data_do_retorno: Date.today - 1) }

			it 'adiciona erro no campo data da viagem' do
				@diaria.save
				expect(@diaria.errors[:data_da_viagem]).to include('não pode ser após o retorno')
			end

			it 'não permite criar a diária' do
				@diaria.save
				expect(@diaria.persisted?).to be false
				expect(Contabilidade::Diaria.count).to eql(0)
			end
		end

		context 'quando data do retorno é depois da data da viagem' do
			before(:each) { @diaria = build(:diaria, data_da_viagem: Date.today, data_do_retorno: Date.today + 1) }

			it 'não adiciona erro no campo data da viagem' do
				@diaria.save
				expect(@diaria.errors).to be_empty
			end

			it 'permite criar a diária com sucesso' do
				@diaria.save
				expect(@diaria.persisted?).to be true
				expect(Contabilidade::Diaria.count).to eql(1)
			end
		end
	end

	describe '#data_da_diaria_apos_a_data_da_viagem?' do
		context 'quando a data da diária é após a data da viagem' do
			before(:each) { @diaria = build(:diaria, data_da_portaria: '2016-01-02', data_da_viagem: '2016-01-01') }

			it 'adiciona erro no campo data da portaria' do
				@diaria.save
				expect(@diaria.errors[:data_da_portaria]).to include('não pode ser após a data da viagem')
			end

			it 'não permite criar a diária' do
				@diaria.save
				expect(@diaria.persisted?).to be false
				expect(Contabilidade::Diaria.count).to eql(0)
			end
		end

		context 'quando a data da diária é antes da data da viagem' do
			before(:each) { @diaria = build(:diaria, data_da_portaria: '2016-01-01', data_da_viagem: '2016-01-02') }

			it 'não adiciona erro no campo data da portaria' do
				@diaria.save
				expect(@diaria.errors).to be_empty
			end

			it 'permite criar a diária com sucesso' do
				@diaria.save
				expect(@diaria.persisted?).to be true
				expect(Contabilidade::Diaria.count).to eql(1)
			end
		end
	end

	describe '#valor_total' do
		it 'retorna o valor total da diária' do
			diaria = create(:diaria, valor: 123.0, qtd_de_diarias: 2)
			expect(diaria.valor_total).to eq(246.0)
		end
	end

	describe '#codigo_e_descricao' do
		it 'retorna o número e nome do agente público da diária' do
			diaria = create(:diaria, numero: '1234')
			diaria.agente_publico_municipal.pessoa.nome = 'João'
			expect(diaria.codigo_e_descricao).to eq('1234 - João')
		end
	end

	describe "#situacao_de_pagamento" do
		before(:each) { @diaria = create(:diaria) }

		context 'quando a diária não tem empenho' do
			it 'retorna situação A Empenhar' do
				expect(@diaria.situacao_de_pagamento).to eq('A Empenhar')
			end
		end

		context 'quando a diária tem empenho' do
			context 'e o empenho não está confirmado' do
				it 'retorna situação A Empenhar' do
					create(:empenho_com_diaria, diaria: @diaria, status: :solicitado)
					expect(@diaria.situacao_de_pagamento).to eql('A Empenhar')
				end
			end

			context 'e o empenho está confirmado' do
				before(:each) { @empenho = create(:empenho_com_diaria, diaria: @diaria, status: :confirmado) }

				context 'mas não foi liquidado' do
					it 'retorna situação Empenhada' do
						expect(@diaria.situacao_de_pagamento).to eql('A Liquidar')
					end
				end

				context 'e foi liquidado mas a liquidação foi estornada' do
					it 'retorna situação Empenhada' do
						create(:liquidacao_com_diaria, empenho: @empenho, estornada: true)
						expect(@diaria.situacao_de_pagamento).to eql('A Liquidar')
					end
				end

				# context 'e foi liquidado sem estorno' do
				# 	before(:each) {
				# 		@liquidacao = create(:liquidacao_com_diaria, empenho: @empenho, estornada: false)
				# 	}
				#
				# 	context 'mas não foi pago' do
				# 		it 'retorna situação à liquidar' do
				# 			expect(@diaria.situacao_de_pagamento).to eq('A Liquidar')
				# 		end
				# 	end
				#
				# 	context 'e foi pago' do
				# 		before(:each) {
				# 			@pagamento = create(:pagamento, :com_diaria, liquidacao: @liquidacao)
				# 		}
				#
				# 		context 'mas com estorno' do
				# 			it 'retorna situação Liquidada' do
				# 				@pagamento.estornado = true
				# 				@pagamento.save
				# 				expect(@diaria.situacao_de_pagamento).to eq('A Liquidar')
				# 			end
				# 		end
				#
				# 		context 'sem estorno' do
				# 			it 'retorna situação Paga' do
				# 				@pagamento.estornado = false
				# 				@pagamento.save
				# 				expect(@diaria.reload.situacao_de_pagamento).to eq('Paga')
				# 			end
				# 		end
				# 	end
				# end
			end
		end
	end
end
