Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add import script #440

Merged
merged 1 commit into from
Jul 7, 2024
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
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ group :development, :test do
gem 'brakeman', require: false
# RSpec for more modern testing
gem 'rspec-rails', '~> 5.0'
gem "roo", "~> 2.8"
gem "pry", "~> 0.14.2"
end

group :test do
Expand Down
10 changes: 10 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ GEM
brakeman (4.7.0)
builder (3.2.4)
byebug (11.0.1)
coderay (1.1.3)
concurrent-ruby (1.1.9)
connection_pool (2.2.5)
cookiejar (0.3.3)
Expand Down Expand Up @@ -190,6 +191,9 @@ GEM
request_store (~> 1.1)
pdfkit (0.8.4.1)
pg (0.21.0)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (4.0.6)
puma (4.3.9)
nio4r (~> 2.0)
Expand Down Expand Up @@ -248,6 +252,9 @@ GEM
actionpack (>= 5.0)
railties (>= 5.0)
rollbar (2.22.1)
roo (2.8.3)
nokogiri (~> 1)
rubyzip (>= 1.3.0, < 3.0.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
Expand All @@ -265,6 +272,7 @@ GEM
rspec-mocks (~> 3.10)
rspec-support (~> 3.10)
rspec-support (3.10.2)
rubyzip (2.3.2)
rufus-scheduler (3.4.2)
et-orbi (~> 1.0)
sass (3.7.4)
Expand Down Expand Up @@ -346,6 +354,7 @@ DEPENDENCIES
paper_trail
pdfkit
pg
pry (~> 0.14.2)
puma
pundit (~> 2.1)
pundit-matchers (~> 1.6)
Expand All @@ -354,6 +363,7 @@ DEPENDENCIES
rails-controller-testing
render_anywhere
rollbar
roo (~> 2.8)
rspec-rails (~> 5.0)
sass-rails (~> 5.0)
shoulda-matchers
Expand Down
44 changes: 44 additions & 0 deletions scripts/evaluation_importer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class EvaluationImporter

attr_reader :evaluation, :leader, :principle_data, :user_data,
:point_data, :comment_data, :members, :not_members

def initialize(evaluation:, principles:, users:, points:, comments:)
@evaluation = evaluation
@leader = evaluation.group.leader.user
@principle_data = principles
@user_data = users
@point_data = points
@comment_data = comments
@members = evaluation.group.active_members.map(&:user)
@not_members = []
end

def self.call(evaluation:, principles:, users:, points:, comments:)
new(evaluation: evaluation, principles: principles, users: users, points: points, comments: comments).call
end

def call
ActiveRecord::Base.transaction do
principles = principle_data.map do |attributes|
principle = Principle.new(attributes)
principle.evaluation = evaluation
principle.save!
principle
end
user_data.each.with_index do |user_name, row|
user = members.find { |member| member.full_name == user_name }
not_members << user and next unless user
point_request = PointRequest.create!(user: user, evaluation: evaluation)

point_data[row].each.with_index do |point, col|
next unless point
principle = principles[col]
pd = PointDetail.create!(point_request: point_request, principle: principle, point: point)
comment = comment_data[row][col]
PointDetailComment.create!(point_detail: pd, comment: comment, user: leader) if comment
end
end
end
end
end
71 changes: 71 additions & 0 deletions scripts/evaluation_xlsx_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require 'roo'

class EvaluationXlsxParser
attr_reader :filename, :user_count, :responsibility_count, :work_count, :principle_count

def initialize(filename:,user_count:, responsibility_count:, work_count:)
@filename = filename
@user_count = user_count
@responsibility_count = responsibility_count
@work_count = work_count
@principle_count = responsibility_count + work_count
end

def principles
result = []
sheet = Roo::Spreadsheet.open(filename).sheet(0)
principle_count.times.each do |index|
row = index + 2 # skip first line, indexing starts from 1
result << { name: sheet.cell(row, 1),
max_per_member: sheet.cell(row, 2),
description: sheet.cell(row, 4),
type: index < responsibility_count ? 'RESPONSIBILITY' : 'WORK'
}
end
result
end

def users
result = []
sheet = Roo::Spreadsheet.open(filename).sheet(1)
user_count.times.each do |index|
row = index + 2 # skip first line, indexing starts from 1
result << sheet.cell(row, 1)
end
result
end

def points
result = []
sheet = Roo::Spreadsheet.open(filename).sheet(1)
user_count.times.each do |row|
row += 2
point_row = []
principle_count.times.each do |col|
col += 2
point_row << sheet.cell(row, col)
end
result << point_row
end
result
end

def comments
result = []
sheet = Roo::Spreadsheet.open(filename).sheet(1)
user_count.times.each do |row|
row += 2
comment_row = []
principle_count.times.each do |col|
col += 2
comment_row << sheet.comment(row, col)
end
result << comment_row
end
result
end

def results
{principles: principles, users: users, points: points, comments: comments}
end
end
54 changes: 54 additions & 0 deletions spec/scripts/evaluation_importer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require 'rails_helper'
require './scripts/evaluation_importer'

RSpec.describe EvaluationImporter do
subject(:import) { EvaluationImporter.call(evaluation: evaluation, principles: principles, users: users, points: points, comments: comments) }

let(:evaluation) { create(:evaluation) }
let(:leader) { create(:user, firstname: 'Karcsi', lastname: 'Körvez') }
let(:member) { create(:user, firstname: 'Tibor', lastname: 'Tag') }
let(:users) { [leader, member].map(&:full_name) }
let(:principles) do
[{ name: "Felelősség elv", description: "Felelős munka.", type: "RESPONSIBILITY", max_per_member: 20 },
{ name: "Munka elv", description: "Dolgozni kell.", type: "WORK", max_per_member: 30 }]
end

let(:points) do
[[15, 10], [nil, 20]]
end

let(:comments) do
[['Komment a körveznek', nil], [nil, 'Sokat dologzott']]
end

before do
create(:membership, user: member, group: evaluation.group)
create(:membership, user: leader, group: evaluation.group)
end

it 'creates principles' do
expect { import }.to change { Principle.count }.by(2)
principles.each do |principle_attributes|
expect(Principle.find_by(principle_attributes)).to be_present
end
end

it 'creates point requests' do
expect { import }.to change { PointRequest.count }.by(2)
end

it 'creates points' do
expect { import }.to change { PointDetail.count }.by(3)
expect(PointDetail.joins(:point_request, :principle).find_by(point: 15, 'principles.name': 'Felelősség elv', 'point_requests.user_id': leader.id)).to be_present
expect(PointDetail.joins(:point_request, :principle).find_by(point: 10, 'principles.name': 'Munka elv', 'point_requests.user_id': leader.id)).to be_present
expect(PointDetail.joins(:point_request, :principle).find_by(point: 20, 'principles.name': 'Munka elv', 'point_requests.user_id': member.id)).to be_present
end

it 'creates comments' do
expect { import }.to change { PointDetailComment.count}.by(2)
expect(PointDetailComment.joins(point_detail: :point_request).find_by(comment: 'Komment a körveznek', 'point_requests.user_id': leader.id)).to be_present
expect(PointDetailComment.joins(point_detail: :point_request).find_by(comment: 'Sokat dologzott', 'point_requests.user_id': member.id)).to be_present
end
end
50 changes: 50 additions & 0 deletions spec/scripts/evaluation_xlsx_parser_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'rails_helper'
require './scripts/evaluation_xlsx_parser'

RSpec.describe EvaluationXlsxParser do
subject(:parser) { EvaluationXlsxParser.new(filename: './spec/scripts/test_evaluation.xlsx', user_count: 4,
responsibility_count: 2, work_count: 2) }

it 'reads the principles' do
principles = parser.principles

expect(principles[0]).to include(name: "Körvezető", type: "RESPONSIBILITY", max_per_member: 20,
description: "Körvezető felelőssége.")
expect(principles[1]).to include(name: "Gazdaságis", type: "RESPONSIBILITY", max_per_member: 15,
description: "A kör gazdasági ügyeit intézte.")
expect(principles[2]).to include(name: "Projekt munka", type: "WORK", max_per_member: 30,
description: "A kör projekjein végzett munka.")
expect(principles[3]).to include(name: "Tanfolyam tartás", type: "WORK", max_per_member: 15,
description: "A kör tanfolyamainak megtartása.")
end

it 'reads users' do
users = parser.users

expect(users).to be_eql(["Körvezető Károly", "Gazdaságis Géza", "Projekező Pál", "Tanfolyam Tibor"])
end

it 'reads points' do
points = parser.points

expect(points).to be_eql([[20, 5, 30, 15],
[nil, 15, 20, 5],
[nil, nil, 40, nil],
[nil, nil, 20, 15]])
end

it 'reads comments' do
comments = parser.comments

expect(comments).to be_eql([["Vezette a kört", "Számlákat kezelte", "Sok projekten dolgozott", "5 tanfolyam alklamat tartott"],
[nil, "Kezelte a gazdaságis ügyeket", "Projektezett sokat", "1 tanfolyam alkalom"],
[nil, nil, "Mindent feladatot is megcsinált", nil],
[nil, nil, "Sokat dolgozott", "Megtartott 5 tanfolyamalkalmat"]])
end

it 'has results' do
results = parser.results

expect(results).to be_present
end
end
Binary file added spec/scripts/test_evaluation.xlsx
Binary file not shown.
Loading