Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions app/models/Usuario.rb

This file was deleted.

14 changes: 14 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -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
7 changes: 0 additions & 7 deletions app/models/usuario.rb

This file was deleted.

142 changes: 142 additions & 0 deletions app/services/sigaa_import_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
require 'json'

Check failure on line 1 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
require 'csv'

Check failure on line 2 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

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'

Check failure on line 25 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
process_json
when '.csv'

Check failure on line 27 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
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|

Check failure on line 59 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
# Assumindo estrutura do CSV
turma_data = {
'codigo' => row['codigo_turma'],

Check failure on line 62 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Check failure on line 62 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
'nome' => row['nome_turma'],

Check failure on line 63 in app/services/sigaa_import_service.rb

View workflow job for this annotation

GitHub Actions / lint

Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
'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
65 changes: 65 additions & 0 deletions test/services/sigaa_import_service_test.rb
Original file line number Diff line number Diff line change
@@ -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
Loading