Skip to content
This repository has been archived by the owner on Jul 24, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1039 from YaleSTC/273_item_history
Browse files Browse the repository at this point in the history
resolves #273
  • Loading branch information
orenyk committed Nov 16, 2014
2 parents f85e601 + 081f02e commit 7b5999a
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 39 deletions.
21 changes: 13 additions & 8 deletions app/controllers/equipment_objects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def new

def create
@equipment_object = EquipmentObject.new(equipment_object_params)
@equipment_object.notes = "#### Created at #{Time.current.to_s(:long)} by #{current_user.md_link}"
if @equipment_object.save
flash[:notice] = "Successfully created equipment object. #{@equipment_object.serial}"
redirect_to @equipment_object.equipment_model
Expand All @@ -52,19 +53,21 @@ def update
# Delete deactivation reason when "Disabled?" is toggled
p[:deactivation_reason] = ""
end

if @equipment_object.update_attributes(p)
@equipment_object.update(current_user, p)
if @equipment_object.save
flash[:notice] = "Successfully updated equipment object."
redirect_to @equipment_object.equipment_model
redirect_to @equipment_object
else
render action: 'edit'
end
end

# Deactivate and activate extend controller methods in ApplicationController
def deactivate
def deactivate
if params[:deactivation_reason] && !params[:deactivation_cancelled]
@equipment_object.update_attributes(deactivation_reason: params[:deactivation_reason])
# update notes and deactivate
new_notes = "#### Deactivated at #{Time.current.to_s(:long)} by #{current_user.md_link}\n#{params[:deactivation_reason]}\n\n" + @equipment_object.notes
@equipment_object.update_attributes(deactivation_reason: params[:deactivation_reason], notes: new_notes)
# archive current reservation if any
@equipment_object.current_reservation.archive(current_user, "The equipment item was deactivated for the following reason: **#{params[:deactivation_reason]}**").save(validate: false) if @equipment_object.current_reservation
super
Expand All @@ -79,13 +82,15 @@ def deactivate

def activate
super
@equipment_object.update_attributes(deactivation_reason: nil)
new_notes = "#### Reactivated at #{Time.current.to_s(:long)} by #{current_user.md_link}\n\n" + @equipment_object.notes
@equipment_object.update_attributes(deactivation_reason: nil, notes: new_notes)
end

private

def equipment_object_params
params.require(:equipment_object).permit(:name, :serial, :equipment_model_id,
:deleted_at, :deactivation_reason)
params.require(:equipment_object).permit(:name, :serial, :deleted_at,
:equipment_model_id,
:deactivation_reason, :notes)
end
end
48 changes: 33 additions & 15 deletions app/controllers/reservations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,46 @@ def edit
def update # for editing reservations; not for checkout or check-in
message = "Successfully edited reservation."
res = reservation_params

# update attributes
# add new equipment object id to hash if it's being changed and save old
# and new objects for later
unless params[:equipment_object].blank?
object = EquipmentObject.find(params[:equipment_object])
unless object.available?
r = object.current_reservation
res[:equipment_object_id] = params[:equipment_object]
new_object = EquipmentObject.find(params[:equipment_object])
old_object = @reservation.equipment_object_id ? EquipmentObject.find(@reservation.equipment_object_id) : nil
# check to see if new object is available
unless new_object.available?
r = new_object.current_reservation
r.equipment_object_id = @reservation.equipment_object_id
r.save
message << " Note equipment item #{r.equipment_object.name} is now assigned to \
#{ActionController::Base.helpers.link_to('reservation #' + r.id.to_s, reservation_path(r))} \
(#{r.reserver.render_name})"
end
res[:equipment_object_id] = params[:equipment_object]
end

# save changes to database
@reservation.update(current_user, res, params[:new_notes])
@reservation.save
if @reservation.save
# code for switching equipment objects
unless params[:equipment_object].blank?
# if the item was previously assigned to a different reservation
if r
r.save
# clean up this code with a model method?
message << " Note equipment item #{r.equipment_object.name} is now assigned to \
#{ActionController::Base.helpers.link_to('reservation #' + r.id.to_s, reservation_path(r))} \
(#{r.reserver.render_name})"
end

# flash success and exit
flash[:notice] = message
redirect_to @reservation
# update the item history / histories
old_object.make_switch_notes(@reservation, r, current_user) if old_object
new_object.make_switch_notes(r, @reservation, current_user)
end

# flash success and exit
flash[:notice] = message
redirect_to @reservation
else
# if it couldn't save
flash[:error] = 'There was a problem updating the reservation.'
redirect_to :back
end
end

def checkout
Expand All @@ -154,7 +172,7 @@ def checkout
r = Reservation.find(r_id)
checked_out_reservations << r.checkout(r_attrs[:equipment_object_id],
current_user,
r_attrs[:checkout_procedures],
Hash.new(r_attrs[:checkout_procedures]),
r_attrs[:notes])
end

Expand Down
55 changes: 51 additions & 4 deletions app/models/equipment_object.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class EquipmentObject < ActiveRecord::Base

include Searchable
include Rails.application.routes.url_helpers

has_paper_trail

Expand Down Expand Up @@ -31,10 +32,7 @@ def status
end

def current_reservation
self.reservations.each do |r|
return r if r.checked_out && r.checked_in.nil?
end
return nil
return self.reservations.checked_out.first
end

def available?
Expand All @@ -53,4 +51,53 @@ def self.for_eq_model(model_id,source_objects)
count
end

def make_reservation_notes(procedure_verb, reservation, handler, new_notes, time)
new_str = "#### [#{procedure_verb.capitalize}](#{reservation_path(reservation.id)}) by #{handler.md_link} for #{reservation.reserver.md_link} on #{time.to_s(:long)}\n"
unless new_notes.empty?
new_str += "##### Notes:\n#{new_notes}\n\n"
else
new_str += "\n"
end
new_str += self.notes
self.update_attributes(notes: new_str)
end

def make_switch_notes(old_res, new_res, handler)
# set text depending on whether or not reservations are passed in
old_res_msg = old_res ? old_res.md_link : 'available'
new_res_msg = new_res ? new_res.md_link : 'available'
self.update_attributes(notes: "#### Switched by #{handler.md_link} from #{old_res_msg} to #{new_res_msg} on #{Time.current.to_s(:long)}\n\n" + self.notes)
end

def update(current_user, new_params)
self.assign_attributes(new_params)
changes = self.changes
if changes.empty?
self
return
else
new_notes = "#### Edited at #{Time.current.to_s(:long)} by #{current_user.md_link}\n\n"
new_notes += "\n\n#### Changes:"
changes.each do |param, diff|
case param
when 'name'
name = 'Name'
old_val = diff[0].to_s
new_val = diff[1].to_s
when 'serial'
name = 'Serial'
old_val = diff[0].to_s
new_val = diff[1].to_s
when 'equipment_model_id'
name = 'Equipment Model'
old_val = diff[0] ? EquipmentModel.find(diff[0]).name : 'nil'
new_val = diff[1] ? EquipmentModel.find(diff[1]).name : 'nil'
end
new_notes += "\n#{name} changed from " + old_val + " to " + new_val + "." if (old_val && new_val)
end
end
new_notes += "\n\n" + self.notes
self.notes = new_notes.strip
self
end
end
19 changes: 15 additions & 4 deletions app/models/reservation.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Reservation < ActiveRecord::Base
include ReservationValidations
include ReservationScopes
include Rails.application.routes.url_helpers

has_paper_trail

Expand Down Expand Up @@ -172,17 +173,20 @@ def checkin(checkin_handler, procedures, new_notes)
# gather all the procedure texts that were not
# checked, ie not included in the procedures hash
incomplete_procedures = []
procedures = [procedures].flatten # in case of nil procedures
self.equipment_model.checkin_procedures.each do |checkin_procedure|
if procedures.exclude?(checkin_procedure.id.to_s)
incomplete_procedures << checkin_procedure.step
end
end
self.make_notes("Checked in", new_notes, incomplete_procedures, checkin_handler)
# update equipment object notes
self.equipment_object.make_reservation_notes("checked in", self, checkin_handler, new_notes, Time.current)

if self.checked_in.to_date > self.due_date.to_date
# equipment was overdue, send an email confirmati
AdminMailer.overdue_checked_in_fine_admin(r).deliver
UserMailer.overdue_checked_in_fine(r).deliver
AdminMailer.overdue_checked_in_fine_admin(self).deliver
UserMailer.overdue_checked_in_fine(self).deliver
end

self
Expand Down Expand Up @@ -216,12 +220,15 @@ def checkout(eq_object, checkout_handler, procedures, new_notes)
self.equipment_object_id = eq_object

incomplete_procedures = []
procedures = [procedures].flatten
self.equipment_model.checkout_procedures.each do |checkout_procedure|
if procedures.exclude?(checkout_procedure.id.to_s)
incomplete_procedures << checkout_procedure.step
end
end
self.make_notes("Checked out", new_notes, incomplete_procedures, checkout_handler)
# update equipment object notes
self.equipment_object.make_reservation_notes("checked out", self, checkout_handler, new_notes, Time.current)
self
end

Expand All @@ -239,7 +246,7 @@ def update(current_user, new_params, new_notes)
return
else
# write notes header
header = "### Edited on #{Time.current.to_s(:long)} by #{current_user.name}\n"
header = "### Edited on #{Time.current.to_s(:long)} by #{current_user.md_link}\n"
self.notes = self.notes ? self.notes + "\n" + header : header

# add notes if they exist
Expand Down Expand Up @@ -285,7 +292,7 @@ def make_notes(procedure_verb, new_notes, incomplete_procedures, current_user)
# procedure_kind

# write notes header
header = "### #{procedure_verb} on #{Time.current.to_s(:long)} by #{current_user.name}\n"
header = "### #{procedure_verb} on #{Time.current.to_s(:long)} by #{current_user.md_link}\n"
self.notes = self.notes ? self.notes + "\n" + header : header

# If no new notes and no missed procedures, set e-mail flag to false and
Expand Down Expand Up @@ -319,4 +326,8 @@ def markdown_listify(items)
return '* ' + items.join("\n* ")
end

def md_link
"[res. \##{self.id.to_s}](#{reservation_path(self)})"
end

end
6 changes: 6 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require 'net/ldap'

class User < ActiveRecord::Base
include Rails.application.routes.url_helpers

has_many :reservations, foreign_key: 'reserver_id', dependent: :destroy
has_and_belongs_to_many :requirements,
class_name: "Requirement",
Expand Down Expand Up @@ -88,6 +90,10 @@ def render_name
"#{name} #{login}"
end

def md_link
"[#{self.name}](#{user_path(self)})"
end


# ---- Reservation methods ---- #

Expand Down
2 changes: 0 additions & 2 deletions app/views/equipment_objects/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,5 @@
<%= f.association :equipment_model, placeholder: 'Please select an equipment model...' %>
<%=f.input :name%>
<%=f.input :serial%>
<%=f.input :deleted_at, :as => :deleted, label: "Disabled"%>
<%=f.input :deactivation_reason, label: "Reason for deactivation?"%>
<%= f.button :wrapped, :cancel => equipment_objects_path %>
<% end %>
12 changes: 12 additions & 0 deletions app/views/equipment_objects/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
<strong>Status:</strong>
<%= @equipment_object.status %>
</p>

<%# NOTES %>
<div class="row">
<div class="span9">
<% unless @equipment_object.notes.blank? %>
<hr>
<h3>Notes</h3>
<div class='notes-container'><%= markdown(@equipment_object.notes) %></div>
<% end %>
</div>
</div>

<div class="form-actions">
<%= link_to "Edit", edit_equipment_object_path(@equipment_object), class: 'btn' %>
<%= make_deactivate_btn :equipment_objects, @equipment_object %>
Expand Down
17 changes: 17 additions & 0 deletions db/migrate/20141001000934_add_notes_to_equipment_objects.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class AddNotesToEquipmentObjects < ActiveRecord::Migration
def change
add_column :equipment_objects, :notes, :text, limit: 16777215, null: false

# go through all existing equipment objects, including reservations and
# associated users
EquipmentObject.includes(reservations: [:reserver, :checkout_handler, :checkin_handler]).all.each do |eo|
# add creation note
eo.update_attributes(notes: "#### Created at #{eo.created_at.to_s(:long)}")
# go through all reservations and make notes
eo.reservations.sort_by(&:checked_out).each do |res|
eo.make_reservation_notes('checked_out', res, res.checkout_handler, '', res.checked_out) if res.checked_out
eo.make_reservation_notes('checked_in', res, res.checkin_handler, '', res.checked_in) if res.checked_in
end
end
end
end
7 changes: 4 additions & 3 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20140930233633) do
ActiveRecord::Schema.define(version: 20141001000934) do

create_table "announcements", force: true do |t|
t.text "message"
Expand Down Expand Up @@ -132,13 +132,14 @@
create_table "equipment_objects", force: true do |t|
t.string "name"
t.string "serial"
t.boolean "active", default: true
t.boolean "active", default: true
t.integer "equipment_model_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "deleted_at"
t.boolean "csv_import", default: false, null: false
t.boolean "csv_import", default: false, null: false
t.string "deactivation_reason"
t.text "notes", limit: 16777215, null: false
end

create_table "requirements", force: true do |t|
Expand Down
2 changes: 2 additions & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ def deleted_missed_reservation_email_body
eo.serial = (0...8).map{65.+(rand(25)).chr}.join
eo.active = true
eo.equipment_model_id = equipment_model.flatten.sample.id
eo.notes = ''
end
end
puts "\n#{entered_num} equipment object records successfully created!"
Expand Down Expand Up @@ -545,6 +546,7 @@ def deleted_missed_reservation_email_body
res.checked_in = [nil, time_rand(random_time_in_future, random_time_in_future.next_week,
res.equipment_model.category.max_checkout_length).to_datetime].sample
res.checked_out = res.checked_in.nil? ? [nil, random_time_in_future.to_datetime].sample : random_time_in_future.to_datetime
res.equipment_object_id = res.checked_out ? res.equipment_object_id : nil
res.notes = Faker::HipsterIpsum.paragraph(8)
res.notes_unsent = [true, false].sample
end
Expand Down
1 change: 1 addition & 0 deletions lib/equipment_import.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def import_objects(processed_objects)

# if new object is valid, save to database and add to array of success
if object.valid?
object.notes = "#### Created at #{Time.current.to_s(:long)} via import"
object.save
array_of_success << object
# else, store to array of fail with error messages
Expand Down
Loading

0 comments on commit 7b5999a

Please sign in to comment.