vegantech/sims

View on GitHub
lib/csv_importer/users.rb

Summary

Maintainability
A
0 mins
Test Coverage
module CSVImporter
  class Users < CSVImporter::Base
    FIELD_DESCRIPTIONS = { 
        :district_user_id =>"Key for user (30 char limit)",
        :username =>"Used at login (30 char limit)",
        :first_name =>"First Name",
        :middle_name =>"Middle Name",
        :last_name =>"Last Name",
        :suffix =>"Suffix",
        :email =>"Email address (must be valid)",
        :passwordhash =>'The encoded password.   Encode the password using the following:  
SHA1.encode("#{system_hash}#{password.downcase}#{district_key}#{salt}")
  replacing the #{} with the appropriate values.  system_hash is currently blank.   
password is the user\'s password in lowercase, district_key is set by the district admin, and the salt is the next field',
        :salt =>"A random value used in the password hash"
    }
    class << self
      def description
        "Users in the district.  Note you can leave the password and salt blank, if so then be sure to set a district_key and make sure the email is present.
        The district key acts as an initial password, which users will change when they first login."
      end

      def csv_headers
        [:district_user_id, :username, :first_name, :middle_name, :last_name, :suffix, :email, :passwordhash, :salt]
      end

      def optional_headers
        [:passwordhash, :salt]
      end

      def overwritten
        "Users with matching district_user_id in the file will be overwritten."
      end

      def load_order
        "2. This should be uploaded before most other files."
      end

      def removed
        "Users with district_user_id assigned but not in the file are removed from the district."
      end

#      def related
#      end

      def how_often
        "Start of each semester (depending on frequency of new staff may need to be done more or less often)."
      end

      def how_many_rows
        "One row per user."
      end

#      def alternate
#      end

      def upload_responses
        super
      end

    end



  private
    def index_options
      [:district_user_id ]
    end

    def csv_headers
      self.class.csv_headers
    end

    def migration t
      @cols = User.columns_hash
      migrate_cols(t,@cols)
    end


    def update
    updates=csv_headers[0..-3].collect{|e| "u.#{e} = tu.#{e}"}.join(", ")
    query = ("update users u
      inner join #{temporary_table_name} tu
      on u.district_user_id = tu.district_user_id and u.district_user_id is not null
      set u.updated_at=CURDATE(), 
      #{updates}
    where district_id = #{@district.id}"
    )

    User.connection.update query

    end

    def insert_update_delete
      @deleted=delete
      @updated=update
      @created=insert
      @other_messages << "#{update_passwords} passwords updated"
    end



    def delete
     query = "select id from users u left outer join #{temporary_table_name} tu
        on u.district_user_id = tu.district_user_id
        where u.district_user_id !='' and u.district_id = #{@district.id}
        and tu.district_user_id is null"
      user_ids_to_remove=User.connection.select_rows(query)
      User.remove_from_district(user_ids_to_remove)
      user_ids_to_remove.length
    end

    def update_passwords
    updates=csv_headers[-3..-1].collect{|e| "u.#{e} = tu.#{e}"}.join(", ")
    query = ("update users u
      inner join #{temporary_table_name} tu
      on u.district_user_id = tu.district_user_id and u.district_user_id !=''
      set u.updated_at=CURDATE(), 
      #{updates}
    where district_id = #{@district.id} and tu.passwordhash is not null and tu.salt is not null and tu.passwordhash <> '' and tu.salt <> ''"
    )

      User.connection.update query

    end

    def insert
      inserts = csv_headers.join(", ")
      query=("insert into users 
      (#{inserts}, created_at, updated_at, district_id)
      select tu.* , CURDATE(), CURDATE(), #{@district.id} from #{temporary_table_name} tu left outer join users u  
      on tu.district_user_id = u.district_user_id
      and u.district_id = #{@district.id}  
      where
      u.district_user_id is null
      and tu.district_user_id is not null
      "
      )
      User.connection.update query
    end


    def confirm_count?
      model_name = "user"
      model_count = @district.send(model_name.tableize).count(:conditions=>'district_user_id is not null and district_user_id !=""')
        if @line_count < (model_count * ImportCSV::DELETE_PERCENT_THRESHOLD  ) && model_count > ImportCSV::DELETE_COUNT_THRESHOLD
          @messages << "Probable bad CSV file.  We are refusing to delete over 40% of your #{model_name.pluralize} records."
          false
        else
          true
        end
    end
  end
end