Skip to content

Commit

Permalink
Merge pull request #440 from kir-dev/add-import-script
Browse files Browse the repository at this point in the history
add import script
  • Loading branch information
SepsiLaszlo authored Jul 7, 2024
2 parents 758a480 + 3147fb9 commit 99f865e
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 0 deletions.
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.

0 comments on commit 99f865e

Please sign in to comment.