diff --git a/app/models/Usuario.rb b/app/models/Usuario.rb deleted file mode 100644 index 5746bc5f8b..0000000000 --- a/app/models/Usuario.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Usuario < ApplicationRecord - #mais codigo acima assumindo que Usuario ja exista - has_many :matricula_turmas - has_many :turmas, through: :matricula_turmas -end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000000..2e47818df0 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,14 @@ +class User < ApplicationRecord + has_secure_password + has_many :sessions, dependent: :destroy + has_many :matricula_turmas + has_many :turmas, through: :matricula_turmas + + validates :email_address, presence: true, uniqueness: true + validates :login, presence: true, uniqueness: true + validates :matricula, presence: true, uniqueness: true + validates :nome, presence: true + + normalizes :email_address, with: ->(e) { e.strip.downcase } + normalizes :login, with: ->(l) { l.strip.downcase } +end diff --git a/app/models/usuario.rb b/app/models/usuario.rb deleted file mode 100644 index 095adc1d9b..0000000000 --- a/app/models/usuario.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Usuario < ApplicationRecord - has_secure_password - - validates :login, presence: true, uniqueness: true - validates :email, presence: true, uniqueness: true - validates :matricula, presence: true, uniqueness: true -end diff --git a/app/services/sigaa_import_service.rb b/app/services/sigaa_import_service.rb new file mode 100644 index 0000000000..ad82709c80 --- /dev/null +++ b/app/services/sigaa_import_service.rb @@ -0,0 +1,142 @@ +require 'json' +require 'csv' + +class SigaaImportService + def initialize(file_path) + @file_path = file_path + @results = { + turmas_created: 0, + turmas_updated: 0, + usuarios_created: 0, + usuarios_updated: 0, + errors: [] + } + end + + def process + unless File.exist?(@file_path) + @results[:errors] << "Arquivo não encontrado: #{@file_path}" + return @results + end + + begin + ActiveRecord::Base.transaction do + case File.extname(@file_path).downcase + when '.json' + process_json + when '.csv' + process_csv + else + @results[:errors] << "Formato de arquivo não suportado: #{File.extname(@file_path)}" + end + + if @results[:errors].any? + raise ActiveRecord::Rollback + end + end + rescue JSON::ParserError + @results[:errors] << "Arquivo JSON inválido" + rescue ActiveRecord::StatementInvalid => e + @results[:errors] << "Erro de conexão com o banco de dados: #{e.message}" + rescue StandardError => e + @results[:errors] << "Erro inesperado: #{e.message}" + end + + @results + end + + private + + def process_json + file_content = File.read(@file_path) + data = JSON.parse(file_content) + data.each do |turma_data| + process_turma(turma_data) + end + end + + def process_csv + CSV.foreach(@file_path, headers: true, col_sep: ',') do |row| + # Assumindo estrutura do CSV + turma_data = { + 'codigo' => row['codigo_turma'], + 'nome' => row['nome_turma'], + 'semestre' => row['semestre'] + } + + turma = process_turma_record(turma_data) + + if turma&.persisted? + user_data = { + 'nome' => row['nome_usuario'], + 'email' => row['email'], + 'matricula' => row['matricula'], + 'papel' => row['papel'] + } + process_participante_single(turma, user_data) + end + end + end + + def process_turma(data) + turma = process_turma_record(data) + if turma&.persisted? + process_participantes(turma, data['participantes']) if data['participantes'] + end + end + + def process_turma_record(data) + turma = Turma.find_or_initialize_by(codigo: data['codigo'], semestre: data['semestre']) + + is_new_record = turma.new_record? + turma.nome = data['nome'] + + if turma.save + if is_new_record + @results[:turmas_created] += 1 + else + @results[:turmas_updated] += 1 + end + turma + else + @results[:errors] << "Erro ao salvar turma #{data['codigo']}: #{turma.errors.full_messages.join(', ')}" + nil + end + end + + def process_participantes(turma, participantes_data) + participantes_data.each do |p_data| + process_participante_single(turma, p_data) + end + end + + def process_participante_single(turma, p_data) + # Usuario identificado pela matrícula + user = User.find_or_initialize_by(matricula: p_data['matricula']) + + is_new_user = user.new_record? + user.nome = p_data['nome'] + user.email = p_data['email'] + + generated_password = nil + if is_new_user + generated_password = SecureRandom.hex(8) + user.password = generated_password + end + + if user.save + if is_new_user + @results[:usuarios_created] += 1 + UserMailer.cadastro_email(user, generated_password).deliver_now + else + @results[:usuarios_updated] += 1 + end + + matricula = MatriculaTurma.find_or_initialize_by(turma: turma, user: user) + matricula.papel = p_data['papel'] + matricula.save! + else + @results[:errors] << "Erro ao salvar usuário #{p_data['matricula']}: #{user.errors.full_messages.join(', ')}" + end + end +end diff --git a/test/services/sigaa_import_service_test.rb b/test/services/sigaa_import_service_test.rb new file mode 100644 index 0000000000..dd83ccecea --- /dev/null +++ b/test/services/sigaa_import_service_test.rb @@ -0,0 +1,65 @@ +require 'test_helper' + +class SigaaImportServiceTest < ActiveSupport::TestCase + def setup + @file_path = Rails.root.join('tmp', 'sigaa_data.json') + @data = [ + { + "codigo" => "TURMA123", + "nome" => "Engenharia de Software", + "semestre" => "2023.2", + "participantes" => [ + { + "nome" => "João Silva", + "email" => "joao@example.com", + "matricula" => "2023001", + "papel" => "discente" + } + ] + } + ] + File.write(@file_path, @data.to_json) + end + + def teardown + File.delete(@file_path) if File.exist?(@file_path) + end + + test "importa turmas e usuarios com sucesso" do + assert_difference 'ActionMailer::Base.deliveries.size', 1 do + service = SigaaImportService.new(@file_path) + result = service.process + + assert_empty result[:errors] + assert_equal 1, result[:turmas_created] + assert_equal 1, result[:usuarios_created] + end + + turma = Turma.find_by(codigo: "TURMA123") + assert_not_nil turma + assert_equal "Engenharia de Software", turma.nome + + user = User.find_by(matricula: "2023001") + assert_not_nil user + assert_equal "João Silva", user.nome + assert user.authenticate(user.password) if user.respond_to?(:authenticate) # Optional verification if has_secure_password + + matricula = MatriculaTurma.find_by(turma: turma, user: user) + assert_not_nil matricula + assert_equal "discente", matricula.papel + end + + test "reverte em caso de erro de validação" do + # Criar dados inválidos (semestre faltando para Turma) + invalid_data = @data.dup + invalid_data[0]["semestre"] = nil + File.write(@file_path, invalid_data.to_json) + + service = SigaaImportService.new(@file_path) + result = service.process + + assert_not_empty result[:errors] + assert_equal 0, Turma.count + assert_equal 0, User.count + end +end