olympiamanagement/app/controllers/admin/olympiamanagements_controll...

482 lines
20 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class Admin::OlympiamanagementsController < OrbitAdminController
require 'spreadsheet'
require 'rubyXL'
require 'fileutils'
require "axlsx"
before_action :create_first_fields
helper Admin::OlympiamanagementsHelper
load File.expand_path(__dir__)+'/zipgenerator.rb'
def index
end
def add_school_data
SchoolDataFields.create if SchoolDataFields.all.count == 0
@SchoolDataField = SchoolDataFields.first
@olympia_school_data_field = (params[:id].nil? ? OlympiaSchoolDataFields.new : ((OlympiaSchoolDataFields.find(params[:id]).nil? rescue true) ? OlympiaSchoolDataFields.new : OlympiaSchoolDataFields.find(params[:id])))
end
def update_sign_up_data
if params[:type] == "delete_old_data"
else
render :html => params and return
end
end
def update_school_data
if params[:type] == 'class_setting'
@ClassSettingField = (params[:id].nil? ? ClassSettingFields.new : ((ClassSettingFields.find(params[:id]).nil? rescue true) ? ClassSettingFields.new : ClassSettingFields.find(params[:id])))
@ClassSettingField.class_number_range = params[:class_number_range].map{|num| num.to_i}
@ClassSettingField.enrollment_available = params[:enrollment_available].to_i
@ClassSettingField.save
render :json => {'success'=>true} and return
elsif params[:type] == 'delete_class_setting'
if !params[:id].to_s.blank?
begin
ClassSettingFields.find(params[:id]).destroy
rescue
puts 'not_found id='+params[:id]+' in ClassSettingFields'
end
redirect_to :back
end
elsif params[:type] == 'delete_school_data'
if !params[:id].to_s.blank?
begin
OlympiaSchoolDataFields.find(params[:id]).destroy
rescue
puts 'not_found id='+params[:id]+' in OlympiaSchoolDataFields'
end
redirect_to :back
end
elsif params[:type] == 'add_school_data'
@olympia_school_data_field = (params[:id].nil? ? OlympiaSchoolDataFields.new : ((OlympiaSchoolDataFields.find(params[:id]).nil? rescue true) ? OlympiaSchoolDataFields.new : OlympiaSchoolDataFields.find(params[:id])))
params['add_school_data'].keys.each do |field|
@olympia_school_data_field[field] = params['add_school_data'][field]
end
@olympia_school_data_field.save
redirect_to admin_olympiamanagements_school_data_list_path
elsif params[:type] == 'import_class_setting'
if params[:upload_file].nil?
redirect_to admin_olympiamanagements_import_editing_number_of_school_class_path+'?error=true'
else
import_class_setting
end
elsif params[:type] == 'approved'
@olympia_school_data_field = OlympiaSchoolDataFields.find(params[:id]) rescue nil
if @olympia_school_data_field.nil?
render_404_html
else
@olympia_school_data_field.approved = true
@olympia_school_data_field.save
redirect_to :back
end
elsif params[:type] == 'unapproved'
@olympia_school_data_field = OlympiaSchoolDataFields.find(params[:id]) rescue nil
if @olympia_school_data_field.nil?
render_404_html
else
@olympia_school_data_field.approved = false
@olympia_school_data_field.save
redirect_to :back
end
elsif params[:type] == 'sign_up_setting'
@sign_up_setting = SignUpSetting.find(params[:id]) rescue SignUpSetting.where(:active=>true).last
if @sign_up_setting.nil?
render_404_html
else
params["sign_up_setting"].each do |key,value|
@sign_up_setting[key] = value
end
@sign_up_setting.save
redirect_to :back
end
else
render :html => params and return
end
end
def render_404_html
render :html => File.read('app/views/errors/404.html').html_safe
end
def school_data_list
@SchoolDataField = SchoolDataFields.first
@SchoolDataname = @SchoolDataField.school_data_fields.map{|field| field.keys[0]}
page_num = params[:page] || 1
@OlympiaSchoolDataFields = OlympiaSchoolDataFields.all.asc(:id)
@OlympiaSchoolDataFields = @OlympiaSchoolDataFields.where("school_name" => /#{params[:school_name]}/) if !params[:school_name].to_s.blank?
@OlympiaSchoolDataFields = @OlympiaSchoolDataFields.where("school_code" => /#{params[:school_code]}/) if !params[:school_code].to_s.blank?
@OlympiaSchoolDataFields = @OlympiaSchoolDataFields.page(page_num).per(10)
end
def class_setting
page_num = params[:page] || 1
@class_setting_list = ClassSettingFields.all.asc(:enrollment_available).page(page_num).per(10)
@ClassSettingField = (params[:id].nil? ? nil : ((ClassSettingFields.find(params[:id]).nil? rescue true) ? nil : ClassSettingFields.find(params[:id])))
end
def import_class_setting
if !params[:upload_file].blank?
flag = read_xlsx_temp_file_and_import_class_setting(params[:upload_file].tempfile,params[:upload_file].original_filename)
if flag == true
redirect_to admin_olympiamanagements_school_data_list_path
else
render 'import_error_msg'
end
end
end
def read_xlsx_temp_file_and_import_class_setting(tempfile,filename)
import_class_setting_check(tempfile,filename)
if !@error_msg.empty?
return false
else
@error_msg = Array.new
@filename = filename.nil? ? tempfile.path : filename
workbook = RubyXL::Parser.parse(tempfile)
sheet = workbook[0].sheet_data.rows
first_index = 0
sheet.each_with_index do |raw_row,index|
row = raw_row.cells.map{ |cell| cell.value rescue nil}
if row.nil? && first_index != -1
first_index += 1
next
elsif row.nil?
next
end
if index == first_index || first_index != -1
first_index = -1
else
#@error_msg << @row_index_hash and return false
@olympia_school_data_field = OlympiaSchoolDataFields.where(:school_code=> row[@row_index_hash["school_code"]]).first
@olympia_school_data_field = OlympiaSchoolDataFields.new() if @olympia_school_data_field.nil?
@row_index_hash.each do |key,index|
@olympia_school_data_field[key] = row[index]
end
@olympia_school_data_field.save
end
end
return true
end
end
def import_class_setting_check(tempfile,filename)
@profile_data_row = [ "school_code", "school_name" , "school_address" ,"class_number","enrollment_limited","school_contact_person_name","department_job_title","office_tel_number","fax","mobile_number","email","enrollment"]
@error_msg = Array.new
@filename = filename.nil? ? tempfile.path : filename
@row_index_hash = {}
begin
workbook = RubyXL::Parser.parse(tempfile)
rescue
@error_msg << filename+'格式錯誤'
return @error_msg
end
sheet = workbook[0].sheet_data.rows
first_index = 0
sheet.each_with_index do |raw_row,index|
begin
row = raw_row.cells.map{ |cell| cell.value rescue nil}
rescue
@error_msg << filename+'格式錯誤'
return @error_msg
end
if row.nil? && first_index != -1
next
elsif row.nil?
next
end
if index == first_index || first_index != -1
@field_data = row
delete_array = []
@profile_data_row.each do |row_key|
if !@field_data.include?(t('olympiamanagement.'+row_key))
delete_array << row_key
else
@row_index_hash[row_key] = @field_data.index(t('olympiamanagement.'+row_key))
end
end
delete_array.each{|element| @profile_data_row.delete(element)}
first_index = -1
else
#@error_msg << @row_index_hash and return
if row[@row_index_hash["school_code"]] == ""
@error_msg << @filename+"#{make_alpha_from_numbers(@row_index_hash['school_code'])}#{index+1}欄位學校代碼不符(該欄位值不可為空)。"
end
end
end
end
def make_alpha_from_numbers(number)
@numeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if number < @numeric.size
@a = @numeric[number]
else
@dev_by = (number/@numeric.size).floor
@a = "#{make_alpha_from_numbers(@dev_by-1)}#{make_alpha_from_numbers(number-(@dev_by*@numeric.size))}";
end
end
def sign_up_setting
@site_locales = Site.first.in_use_locales
@site_locales.delete(I18n.locale)
@site_locales.insert(0,I18n.locale)
end
def export_school_connection_data
@OlympiaSchoolDataFields = OlympiaSchoolDataFields.all.asc(:id)
dir_path = 'tmp/olypiamanagement/'
#FileUtils.rm_r(dir_path, :force => true) if Dir.exist?(dir_path)
FileUtils.mkdir dir_path if !Dir.exist?(dir_path) #create dir for storing tmp_file if dir doesn't exist
@filename = 'school_export.xlsx'
Dir.chdir(dir_path) do
File.open(@filename, 'w') do |f|
f.write render_to_string( :handlers=> [:axlsx], :formats=> [:xlsx] ,:partial=> 'school_export.xlsx',:locals=> {:@OlympiaSchoolDataFields=>@OlympiaSchoolDataFields} )
end
end
tmp_filename_data = File.read(dir_path +@filename)
send_data(tmp_filename_data, type: 'application/xlsx', disposition: 'attachment', filename: @filename)
end
def sign_up_student_data_list
page_num = params[:page] || 1
@field_infos = StudentDataField.first.student_data_fields
@sign_up_setting_id = SignUpSetting.id
@student_fields = OlympiaStudentDataField.where(:olympia_school_data_fields_id=>params[:olympia_school_id],:sign_up_setting_id=>@sign_up_setting_id).asc(:id).page(page_num).per(10)
end
def export_sign_up_student_data
@student_data_fields = OlympiaStudentDataField.all.asc(:id)
dir_path = 'tmp/olypiamanagement/'
#FileUtils.rm_r(dir_path, :force => true) if Dir.exist?(dir_path)
FileUtils.mkdir dir_path if !Dir.exist?(dir_path) #create dir for storing tmp_file if dir doesn't exist
@field_infos = (StudentDataField.first || StudentDataField.new).student_data_fields
@student_data_list = []
@fields = [ "school_code", "school_name" , "StudentName" ,"StudentSex","StudentIDNO","birth_date","StudentClass","StudentPhone","StudentCode","StudentAddress","StudentArea","StudentIdentity"]
@student_data_fields.each do |field|
@tmp_student_data = []
@fields.each do |field_name|
@value = field[field_name] rescue ""
@index = @field_infos.map{|hash| hash.keys[0]}.index(field_name) rescue nil
if !@index.nil?
if !['String','Year','select_num','File'].include?(@field_infos.map{|hash| hash.values[0]}[@index]['type'])
@value = (@field_infos.map{|hash| hash.values[0]}[@index]['values'][I18n.locale.to_s][@value.to_i].to_s rescue @value)
end
else
if field_name == 'birth_date'
@value = "#{field.StudentBirthYear}-#{field.StudentBirthMonth}-#{field.StudentBirthDay}"
else
@school = OlympiaSchoolDataFields.find(field.olympia_school_data_fields_id) rescue nil
if !@school.nil?
@value = @school[field_name].to_s
end
end
end
@tmp_student_data << @value
end
@student_data_list << @tmp_student_data
end
#render :html => @student_data_list and return
@filename = 'student_export.xlsx'
Dir.chdir(dir_path) do
File.open(@filename, 'w') do |f|
f.write render_to_string( :handlers=> [:axlsx], :formats=> [:xlsx] ,:partial=> 'student_export.xlsx',:locals=> {:@student_data_list=>@student_data_list,:@fields=>@fields} )
end
end
tmp_filename_data = File.read(dir_path +@filename)
send_data(tmp_filename_data, type: 'application/xlsx', disposition: 'attachment', filename: @filename)
end
def download_scan_file_of_certificate
@sign_up_setting_id = @sign_up_setting.id
if !params[:student_id].to_s.blank?
@student = OlympiaStudentDataField.find(params[:student_id]) rescue nil
if @student.nil?
redirect_to :back
else
tmp_filename_data = @student.olympia_student_images.last.student_file.file.read
send_data(tmp_filename_data, type: 'image/jpg', disposition: 'attachment', filename: "#{@student.StudentName}.jpg")
end
else
@student_data_list = OlympiaStudentDataField.where(:sign_up_setting_id=>@sign_up_setting_id)
@student_data_image_path_arr = @student_data_list.flat_map{|student_data| student_data.olympia_student_images}.map{|student_image| student_image.student_file.file.file}
zip_path = "tmp/student_images/#{@sign_up_setting_id}/"
tmp_filename = ''
FileUtils.rm_r(zip_path, :force => true) if Dir.exist?(zip_path)
FileUtils.mkdir_p zip_path #create dir for storing tmp_file
@student_data_image_path_arr.each do |image_path|
@pathname = Pathname.new(image_path)
@temp_name = @pathname.basename
Dir.chdir(@pathname.dirname.to_s) do
@index = 1
@original_filename =@pathname.basename.to_s
@new_pathname = Pathname.new("#{Rails.root}/#{zip_path}#{@original_filename}")
while @new_pathname.exist? do
@new_pathname = Pathname.new(@new_pathname.to_s.insert(@new_pathname.to_s.rindex('.'),"-#{@index}"))
@index += 1
end
#a[0...b].concat('-1').concat(a[b..-1])
FileUtils.cp(@original_filename,@new_pathname)
end
end
@filename = Pathname.new(zip_path).parent.to_s+"/#{Time.now.strftime('%Y_%m_%d')}_student_images.zip"
zip_file= ZipFileGenerator.new(zip_path,@filename)
begin
zip_file.write
rescue
File.delete(@filename)
zip_file.write
end
tmp_filename_data = File.read(@filename)
send_data(tmp_filename_data, type: 'application/zip', disposition: 'attachment', filename: Pathname.new(@filename).basename.to_s)
end
end
def add_sign_up_student_data
@olympia_school_data_field = OlympiaSchoolDataFields.find(params[:school_id]) rescue nil
redirect_to :back if @olympia_school_data_field.nil?
@required_fields = [:school_contact_person_name,:department_job_title,:office_tel_number,:fax,:mobile_number,:email]
@flag = true
@required_fields.each do |field|
if @olympia_school_data_field[field].to_s.blank?
@flag = false
break
end
end
if !@flag
I18n.t('olympiamanagement.please_set_school_connect_data')
@error_msg << "<p><a href=#{school_connection_data_olympiamanagements_path}>#{I18n.t('olympiamanagement.please_set_school_connect_data')}</a></p>"
render 'import_error_msg'
else
@student_data_field = StudentDataField.first
@olympia_student_data = (OlympiaStudentDataField.find(params[:id]) rescue OlympiaStudentDataField.new)
end
end
def update_student_data
if params[:type] == 'add_student_data'
@error_msg = []
@student_params = params.require(:add_student_data).permit!
@all_fields_name = (StudentDataField.first || StudentDataField.new).student_data_fields.map{|hash| hash.keys[0]}
if @student_params.select{|key,value| !value.to_s.blank?}.count < @all_fields_name.slice(0,@all_fields_name.count-1).count
@error_msg << "缺少#{@all_fields_name.slice(0,@all_fields_name.count-1).count-@student_params.select{|key,value| !value.to_s.blank?}.count}個欄位值"
end
@student_params.select{|key,value| value.to_s.blank?}.keys.each do |key|
@error_msg << "#{I18n.t('olympiamanagement.'+key)}欄位值為空"
end
@id_error_msg = checkid(@student_params['StudentIDNO'])
if @id_error_msg.length != 0
@error_msg << @id_error_msg
end
if @student_params['StudentIdentity'] == '1' && (@student_params['olympia_student_images']['0']['StudentFile'].nil? rescue true)
@error_msg << I18n.t('olympiamanagement.StudentFile')
end
@olympia_school_data_field = OlympiaSchoolDataFields.find(params[:school_id]) rescue nil
@enrollment_limited = ((@olympia_school_data_field.enrollment_limited.nil? || @olympia_school_data_field.enrollment_limited == 0) ? ClassSettingFields.all.select{|class_setting_field| class_setting_field.class_number_range[0] <= @olympia_school_data_field.class_number.to_i && class_setting_field.class_number_range[1] >= @olympia_school_data_field.class_number.to_i}.first.enrollment_available.to_i : @olympia_school_data_field.enrollment_limited.to_i)
@student_fields = OlympiaStudentDataField.where(:olympia_school_data_fields_id=>params[:school_id],:sign_up_setting_id=>@sign_up_setting_id)
if @student_fields.length > @enrollment_limited
@error_msg << ((I18n.locale.to_s == "zh_tw") ? ("一般身分報名人數上限為 #{@enrollment_limited} 人。") : ("Enrollment limited of General identity is #{@enrollment_limited} people."))
@error_msg << I18n.t('olympiamanagement.already_exceed_enrollment_limited')
end
if @error_msg.empty?
@olympia_student_data = OlympiaStudentDataField.find(params[:id]) rescue nil
if @olympia_student_data.nil?
@olympia_student_data = OlympiaStudentDataField.create(@student_params)
@olympia_student_data.olympia_school_data_fields_id = @olympia_school_data_field.id
@olympia_student_data.sign_up_setting_id = @sign_up_setting.id
@olympia_student_data.save
else
@olympia_student_data.update_attributes(@student_params)
end
redirect_to admin_olympiamanagements_sign_up_student_data_list_path+"?olympia_school_id=#{params[:school_id]}"
else
render 'import_error_msg'
end
elsif params[:type] == 'delete_student_data'
@olympia_student_data = OlympiaStudentDataField.find(params[:id]) rescue nil
@olympia_student_data.destroy if !@olympia_student_data.nil?
redirect_to :back
else
render :html => '404'
end
end
def import_editing_number_of_school_class
@olympia_school_data_field = OlympiaSchoolDataFields.new
end
def create_first_fields
StudentDataField.create if StudentDataField.all.length == 0
SchoolDataFields.create if SchoolDataFields.all.length == 0
SignUpSetting.create if SignUpSetting.all.length == 0
@sign_up_setting = SignUpSetting.where(:active=>true).last
end
def download_import_file
@OlympiaSchoolDataFields = OlympiaSchoolDataFields.all.asc(:id)
dir_path = 'tmp/olypiamanagement/'
#FileUtils.rm_r(dir_path, :force => true) if Dir.exist?(dir_path)
FileUtils.mkdir dir_path if !Dir.exist?(dir_path) #create dir for storing tmp_file if dir doesn't exist
@filename = 'import_schoo_class_setting.xlsx'
Dir.chdir(dir_path) do
File.open(@filename, 'w') do |f|
f.write render_to_string( :handlers=> [:axlsx], :formats=> [:xlsx] ,:partial=> 'import_schoo_class_setting.xlsx',:locals=> {:@OlympiaSchoolDataFields=>@OlympiaSchoolDataFields} )
end
end
tmp_filename_data = File.read(dir_path +@filename)
send_data(tmp_filename_data, type: 'application/xlsx', disposition: 'attachment', filename: "#{Time.now.year}#{Time.now.month}#{Time.now.day}_import_schoo_class_setting.xlsx")
end
def checkid(id_number)
@ALP_STR = "ABCDEFGHJKLMNPQRSTUVXYWZIO"
@NUM_STR = "0123456789"
def CheckPID(id_number)
@sMsg = ""
sPID = id_number
if(sPID == '')
@sMsg = "請輸入身分證字號"
elsif (sPID.length != 10)
@sMsg = "身分證字號長度應為 10 "
else
sPID = sPID.upcase.strip
@sMsg = chkPID_CHAR(sPID)
if (@sMsg.length != 0)
return @sMsg
end
@iChkNum = getPID_SUM(sPID)
if (@iChkNum % 10 != 0)
iLastNum = sPID[9].to_i
for i in 0 .. 10
xRightAlpNum = @iChkNum - iLastNum + i
if ((xRightAlpNum % 10) == 0)
@sMsg = "身分證字號最後一個數應為:#{i}"
break
end
end
end
end
return @sMsg;
end
# 身分證字號檢查器 - 檢查合法字元
def chkPID_CHAR(sPID)
@sMsg = ""
#sPID = sPID.upcase.strip;
iPIDLen = String(sPID).length
sChk = @ALP_STR + @NUM_STR
for i in 0 ... iPIDLen
if (sChk.index(sPID[i]) < 0)
@sMsg = "這個身分證字號含有不正確的字元!"
break
end
end
if (@sMsg.length == 0)
if (@ALP_STR.index(sPID[0]) < 0)
@sMsg = "身分證字號第 1 碼應為英文字母(A~Z)。"
elsif ((sPID[1] != "1") && (sPID[1] != "2"))
@sMsg = "身分證字號第 2 碼應為數字(1~2)。"
else
for i in 2 ... iPIDLen
if (@NUM_STR.index(sPID[i]) < 0)
@sMsg = "#{i + 1} 碼應為數字(0~9)。"
break
end
end
end
end
return @sMsg
end
#身份證字號檢查器 - 累加檢查碼
def getPID_SUM(sPID)
@iChkNum = 0
#第 1 碼
@iChkNum = @ALP_STR.index(sPID[0]) + 10
@iChkNum = (@iChkNum / 10) + (@iChkNum % 10 * 9)
# 第 2 - 9 碼
for i in 1 ... (sPID.length - 1)
@iChkNum += sPID[i].to_i * (9 - i)
end
# 第 10 碼
@iChkNum += sPID[9].to_i;
return @iChkNum;
end
return CheckPID(id_number);
end
end