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 page_num = params[:page] || 1 @sign_up_settings = SignUpSetting.all.desc(:id) @sign_up_settings = @sign_up_settings.page(page_num).per(10) 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" @students = OlympiaStudentDataField.where(:sign_up_setting_id=>@sign_up_setting.id) @error_msg = [] if @students.length !=0 @students.destroy_all @error_msg << ((I18n.locale.to_s == "zh_tw") ? "已刪除#{@students.length}筆學生資料" : "Already delete #{@students.length} student data.") else @error_msg << ((I18n.locale.to_s == "zh_tw") ? "尚無學生資料" : "There is no student data yet.") end render 'error_message' elsif params[:type] == "active" @sign_up_setting = SignUpSetting.find(params[:id]) rescue nil if !@sign_up_setting.nil? @sign_up_setting.active = true @sign_up_setting.save end redirect_to :back elsif params[:type] == "view" @sign_up_setting = SignUpSetting.find(params[:id]) rescue nil if !@sign_up_setting.nil? session[:sign_up_setting_id] = params[:id] redirect_to admin_olympiamanagements_school_data_list_path else @error_msg = [] @error_msg << ((I18n.locale.to_s == "zh_tw") ? "查無資料" : "Not found.") render 'error_message' end else render :html => '404' 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_params = params.require(:sign_up_setting).permit! if params[:new_sign_up] == "true" #render :html => @sign_up_params and return SignUpSetting.create(@sign_up_params) redirect_to :back else @sign_up_setting = SignUpSetting.find(params[:id]) rescue SignUpSetting.where(:active=>true).last if @sign_up_setting.nil? render_404_html else @sign_up_setting.update_attributes(@sign_up_params) redirect_to :back end 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.where(:sign_up_setting_id=>@sign_up_setting.id).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 flag = 1 sheet.each_with_index do |raw_row,index| row = raw_row.cells.map{ |cell| (cell.nil?) ? '' : cell.value } rescue nil if row.nil? next end if flag == 1 flag = 0 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 flag = 1 sheet.each_with_index do |raw_row,index| begin row = raw_row.cells.map{ |cell| (cell.nil?) ? '' : cell.value } rescue nil rescue @error_msg << filename+'格式錯誤' return @error_msg end if row.nil? next end if flag == 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)} flag = 0 else #@error_msg << @row_index_hash and return if(row[@row_index_hash["school_code"]] == "" rescue true) begin @error_msg << @filename+"中#{make_alpha_from_numbers(@row_index_hash['school_code'])}#{index+1}欄位學校代碼不符(該欄位值不可為空)。" rescue @error_msg << "#{@filename}檔案格式錯誤" return end 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 = @sign_up_setting.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 if @student_data_list.empty? @error_msg = [] @error_msg << ((I18n.locale.to_s == "zh_tw") ? "尚無學生資料" : "There is no student data yet.") render 'error_message' else @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 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 FileUtils.cp(@original_filename,@new_pathname) end end if !@student_data_image_path_arr.empty? @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) else @error_msg = [] @error_msg << ((I18n.locale.to_s == "zh_tw") ? "尚無學生獎狀掃描檔案。" : 'There is no scan file of certificate yet.' ) render 'error_message' end 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 << "
#{I18n.t('olympiamanagement.please_set_school_connect_data')}
" render 'error_message' 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 'error_message' 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 if session[:sign_up_setting_id].blank? @sign_up_setting = SignUpSetting.where(:active=>true).last else @sign_up_setting = SignUpSetting.find(session[:sign_up_setting_id]) rescue nil end if SignUpSetting.where(:active=>true).last.nil? @sign_up_setting = SignUpSetting.last if @sign_up_setting.nil? @sign_up_setting.active = true @sign_up_setting.save end 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