Skip to content

Commit

Permalink
add entry request reviews and exports
Browse files Browse the repository at this point in the history
  • Loading branch information
SepsiLaszlo authored Jan 9, 2025
1 parent c9e2e13 commit 0094db9
Show file tree
Hide file tree
Showing 27 changed files with 567 additions and 47 deletions.
53 changes: 53 additions & 0 deletions app/assets/javascripts/application/entry_request_review.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const entryRequestReviewUpdateSubjects = {}

async function submitEntryRequestReview(id) {
const statusIndicator = document.getElementById(`entry-request-${id}-status-indicator`)
statusIndicator.className = "uk-icon-keyboard-o uk-float-right"
if (!entryRequestReviewUpdateSubjects[id]) {
const {Subject, debounceTime} = rxjs;
const subject = new Subject();
const result = subject.pipe(debounceTime(1000))
result.subscribe({
next: async () => await updateEntryRequestReview(id),
});
entryRequestReviewUpdateSubjects[id] = result
}
const subject = entryRequestReviewUpdateSubjects[id]
subject.next()
}

async function updateEntryRequestReview(id) {
const statusIndicator = document.getElementById(`entry-request-${id}-status-indicator`)
statusIndicator.className = "uk-icon-cog uk-icon-spin uk-float-right"
const entryType = document.getElementById(`entry-request-${id}-entry-type`).value
const finalized = document.getElementById(`entry-request-${id}-finalized`).checked
const justification = document.getElementById(`entry-request-${id}-justification`).value
const recommendationElements = Array.from(document.getElementsByClassName(`entry-request-${id}-recommendation`))
const recommendations = recommendationElements.map((element) => {
return {"resort_id": element.getAttribute("data-resort-id"), "value": element.value}
})
try {
const response = await fetch(`/entry_requests/${id}/update_review`, {
method: 'put',
body: JSON.stringify({
"entry_request": {
"entry_type": entryType,
"finalized": finalized,
"justification": justification,
},
"recommendations": recommendations
}),
headers: {
'X-CSRF-TOKEN': getCsrfToken(),
'Content-Type': 'application/json'
}
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
statusIndicator.className = "uk-icon-check uk-float-right"
} catch (error) {
statusIndicator.className = "uk-icon-close uk-float-right"

}
}
4 changes: 4 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ def require_pek_admin
forbidden_page unless current_user.roles.pek_admin?
end

def require_off_season
forbidden_page unless SystemAttribute.offseason?
end

def require_application_or_evaluation_season
redirect_to root_url if SystemAttribute.offseason?
end
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/development_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ def impersonate_role
impersonate(User.first)
when 'group_leader'
impersonate(Group.kirdev.leader.user)
when 'rvt_member'
when 'rvt_leader'
impersonate(Group.rvt.leader.user)
when 'rvt_member'
impersonate(Group.sssl.leader.user)
when 'svie_admin'
impersonate(Group.svie.leader.user)
when 'pek_admin'
Expand Down
48 changes: 46 additions & 2 deletions app/controllers/entry_requests_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
class EntryRequestsController < ApplicationController
before_action :set_evaluation
before_action :set_evaluation, only: [:update]

ALLOWED_ORDERS = ['id', 'entry_type', 'evaluations.group_id']

def update
authorize @evaluation, :update_entry_request?
Expand All @@ -16,10 +18,52 @@ def update
head :unprocessable_entity
end

def review
authorize :entry_request, :review?
@rvt_leader = current_user.roles.rvt_leader?
@resorts = Group.where(id: Group::RESORTS).order(:name)
@entry_requests = EntryRequest.joins(:evaluation).includes(:group, :user).where('evaluations.semester': SystemAttribute.semester.to_s)
.where("entry_requests.entry_type != 'KDO' OR entry_requests.justification != NULL")
if params[:unfinalized] == '1'
@entry_requests = @entry_requests.where(finalized: false)
end
@order = params[:order] || 'id'
raise "unallowed order in EntryRequestsController#review action" if ALLOWED_ORDERS.exclude?(@order)

@entry_requests = @entry_requests.order(@order)
end

def update_review
authorize :entry_request, :update_review?

entry_request = EntryRequest.find(params[:id])
if current_user.roles.rvt_leader?
entry_request.assign_attributes(entry_request_params)
end
resorts = Group.resorts
group_ids_where_the_user_the_leader = Membership.joins(:posts)
.where(user: current_user,
'posts.post_type_id': PostType::LEADER_POST_ID)
.pluck(:group_id)
resorts.each do |resort|
recommendation = params[:recommendations].find { |recommendation| recommendation["resort_id"].to_i == resort.id }
if group_ids_where_the_user_the_leader.include?(resort.id)
entry_request.recommendations[resort.id.to_s] = recommendation['value']
end
end
entry_request.save! if entry_request.changed?

head :ok
end

private

def entry_request_params
params.require(:entry_request).permit(:entry_type, :justification, :finalized)
end

def create_or_update_entry_request
user = User.find(params[:user_id])
user = User.find(params[:user_id])
entry_type = params[:entry_type]

entry_request = EntryRequest.find_or_create_by!(evaluation: @evaluation, user: user)
Expand Down
23 changes: 17 additions & 6 deletions app/controllers/season_admin_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class SeasonAdminController < ApplicationController
before_action :require_rvt_leader
before_action :require_off_season, only: [:export_point_history, :export_active_users, :export_users_with_ab]

def index
@season = SystemAttribute.season
Expand All @@ -21,14 +22,24 @@ def update
redirect_to seasons_path, notice: t(:edit_successful)
end

def export
def export_point_history
semester = SystemAttribute.semester
export = ExportPointHistory.call(semester.to_s)
csv = CSV.generate do |lines|
export.each do |line|
lines << line
end
end
csv = array_to_csv(export)
send_data(csv, filename: "kozossegi-pont-expot-#{semester}.csv", type: "text/csv")
end

def export_users_with_ab
semester = SystemAttribute.semester
export = ExportUsersWithAb.call(semester.to_s)
csv = array_to_csv(export)
send_data(csv, filename: "ab-nevsor-export-#{semester}.csv", type: "text/csv")
end

def export_active_users
semester = SystemAttribute.semester
export = ExportActiveUsers.call(semester.to_s)
csv = array_to_csv(export)
send_data(csv, filename: "aktiv-kozelok-export-#{semester}.csv", type: "text/csv")
end
end
14 changes: 13 additions & 1 deletion app/controllers/sub_groups_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class SubGroupsController < ApplicationController
before_action :set_sub_group, only: [:show, :edit, :update, :destroy, :join, :leave]
before_action :require_sssl
before_action :create_evaluation_if_not_present, only: [:index]
# GET /sub_groups
def index
@sub_group = SubGroup.new(group: current_group)
Expand All @@ -16,7 +17,7 @@ def show
authorize @sub_group
@policy = policy(@sub_group)
@sub_group_memberships = @sub_group.sub_group_memberships.includes(membership: :user)
@sub_group_principle_policy = SubGroupPrinciplePolicy.new(current_user, @sub_group)
@sub_group_principle_policy = SubGroupPrinciplePolicy.new(current_user, @sub_group)
@sub_group_evaluation_policy = SubGroupEvaluationPolicy.new(current_user, @sub_group)
end

Expand Down Expand Up @@ -105,4 +106,15 @@ def sub_group_params
def current_membership
@current_membership ||= current_user.membership_for(current_group)
end

def create_evaluation_if_not_present
evaluation = Evaluation.find_by(group_id: current_group.id, semester: current_semester)
return if evaluation.present?

evaluation = Evaluation.new(group_id: current_group.id,
creator_user_id: current_user.id,
semester: current_semester)
evaluation.set_default_values
evaluation.save!
end
end
8 changes: 8 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,12 @@ def random_cat_image
def hu_compare(a, b)
HungarianComparator.compare(a, b)
end

def array_to_csv(array)
CSV.generate do |lines|
array.each do |line|
lines << line
end
end
end
end
12 changes: 12 additions & 0 deletions app/helpers/entry_request_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module EntryRequestHelper
def resort_recommendations_tooltip(recommendations)
result = []

recommendations_by_type = recommendations.sort_by { |resort_id, recommendation| recommendation}
recommendations_by_type.each do |resort_id, recommendation|
resort = @resorts.find{|r| r.id == resort_id.to_i}
result << "#{Rails.configuration.x.entry_types[recommendation]} - #{resort.name}"
end
result.join("\n")
end
end
14 changes: 9 additions & 5 deletions app/models/entry_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
#
# Table name: entry_requests
#
# id :bigint not null, primary key
# entry_type :string(255)
# justification :text
# evaluation_id :bigint not null
# user_id :bigint
# id :bigint not null, primary key
# entry_type :string(255)
# finalized :boolean default(FALSE), not null
# justification :text
# recommendations :jsonb not null
# evaluation_id :bigint not null
# user_id :bigint
#
# Indexes
#
# bel_tipus_idx (entry_type)
# index_entry_requests_on_evaluation_id_and_user_id (evaluation_id,user_id) UNIQUE
# index_entry_requests_on_finalized (finalized)
#
# Foreign Keys
#
Expand All @@ -24,6 +27,7 @@ class EntryRequest < ApplicationRecord

belongs_to :evaluation
belongs_to :user
has_one :group, through: :evaluation

validates :evaluation_id, uniqueness: { scope: :user_id }
validate :correct_user
Expand Down
11 changes: 9 additions & 2 deletions app/models/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,21 @@ class Group < ApplicationRecord
belongs_to :group, foreign_key: :parent_id, optional: true
alias own_post_types post_types

scope :resorts, -> { where(parent_id: Group::RVT_ID) }

SVIE_ID = 369
RVT_ID = 146
KIRDEV_ID = 106
KB_ID = 1
SIMONYI_ID = 16
SSSL_ID = 18
KSZK_ID = 47
FALATOZO_ID = 235
BULIS_ID = 144
SPORT_ID = 12
KULTUR_ID = 58
ERDEKVEDELMI_ID = 427

RESORTS = [ SIMONYI_ID, SSSL_ID, KSZK_ID, FALATOZO_ID, BULIS_ID, SPORT_ID, KULTUR_ID, ERDEKVEDELMI_ID ]
scope :resorts, -> { where(id: RESORTS) }

enum type: {
group: 'group',
Expand Down
19 changes: 19 additions & 0 deletions app/policies/entry_request_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class EntryRequestPolicy < ApplicationPolicy
def review?
return false if SystemAttribute.offseason?

pek_admin? || rvt_leader? || resort_leader?
end

alias update_review? review?

private

def rvt_leader?
user.leader_of?(Group.rvt)
end

def resort_leader?
Group.resorts.any? { |resort| user.leader_of?(resort) }
end
end
24 changes: 24 additions & 0 deletions app/services/export_active_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class ExportActiveUsers
attr_reader :semester

def initialize(semester)
@semester = semester
end

def self.call(semester)
new(semester).call
end

def call
result = []
result << ["Név","Email"]
users = User.joins(:point_history).where("point_histories.point > 0")
.where("point_histories.semester": [SystemAttribute.semester.previous.to_s, SystemAttribute.semester.to_s])
.order(:lastname).distinct

users.each do |user|
result << [user.full_name, user.email]
end
result
end
end
26 changes: 26 additions & 0 deletions app/services/export_users_with_ab.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class ExportUsersWithAb
attr_reader :semester

def initialize(semester)
@semester = semester
end

def self.call(semester)
new(semester).call
end

def call
result = []
result << ["Név", "Email", "Kör", "Indoklás"]
entry_requests = EntryRequest.includes({evaluation: :group},:user)
.where("evaluations.semester": SystemAttribute.semester.to_s,
"evaluations.entry_request_status": Evaluation::ACCEPTED,
entry_type: "AB")
.order("groups.name", "users.lastname")

entry_requests.each do |entry_request|
result << [entry_request.user.full_name, entry_request.user.email, entry_request.evaluation.group.name, entry_request.justification]
end
result
end
end
Loading

0 comments on commit 0094db9

Please sign in to comment.