require 'pdf/writer' require 'pdf/simpletable' require 'spreadsheet/excel' include Spreadsheet class ChargePeriodsController < ApplicationController before_filter :login_required before_filter :staff_or_admin_required def new @charge_period = ChargePeriod.new end def create @charge_period = ChargePeriod.new(params[:charge_period]) if @charge_period.save flash[:notice] = 'ChargePeriod was successfully created.' redirect_to :controller => 'charge_sets', :action => 'list' else render :action => 'new' end end def edit @charge_period = ChargePeriod.find(params[:id]) end def update @charge_period = ChargePeriod.find(params[:id]) begin if @charge_period.update_attributes(params[:charge_period]) flash[:notice] = 'ChargePeriod was successfully updated.' redirect_to :controller => 'charge_sets', :action => 'list' else render :action => 'edit' end rescue ActiveRecord::StaleObjectError flash[:warning] = "Unable to update information. Another user has modified this charge period." @charge_period = ChargePeriod.find(params[:id]) render :action => 'edit' end end def destroy begin ChargePeriod.find(params[:id]).destroy rescue flash[:warning] = "Cannot delete charge period due to association " + "with one or more charge sets." end redirect_to :controller => 'charge_sets', :action => 'list' end def pdf period = ChargePeriod.find(params[:id]) _pdf = PDF::Writer.new() _pdf.select_font "Helvetica" _pdf.font_size = 16 _pdf.text "\n\n" + SiteConfig.facility_name + " Charges For Period: " + period.name + "\n\n", :justification => :center ############### # SUMMARY PAGE ############### table = PDF::SimpleTable.new table.width = 536 table.position = :right table.orientation = :left table.font_size = 8 table.heading_font_size = 8 charge_sets = ChargeSet.find(:all, :conditions => [ "charge_period_id = ?", period.id ], :order => "name ASC") set_totals = Hash.new(0) for set in charge_sets totals = set.get_totals set_totals['chips'] += totals['chips'] set_totals['chip_cost'] += totals['chip_cost'] set_totals['labeling_cost'] += totals['labeling_cost'] set_totals['hybridization_cost'] += totals['hybridization_cost'] set_totals['qc_cost'] += totals['qc_cost'] set_totals['other_cost'] += totals['other_cost'] set_totals['total_cost'] += totals['total_cost'] table.data << {"Charge Set" => set.name, "Budget/PO" => set.budget, "Chips" => totals['chips'], "Chip Charge" => fmt_dollars(totals['chip_cost']), "Labeling Charge" => fmt_dollars(totals['labeling_cost']), "Hyb/Wash/Stain/\nScan Charge" => fmt_dollars(totals['hybridization_cost']), "QC Cost" => fmt_dollars(totals['qc_cost']), "Other Cost" => fmt_dollars(totals['other_cost']), "Total Cost" => fmt_dollars(totals['total_cost'])} end # show totals table.data << {"Charge Set" => "TOTALS", "Budget/PO" => "", "Chips" => set_totals['chips'], "Chip Charge" => fmt_dollars(set_totals['chip_cost']), "Labeling Charge" => fmt_dollars(set_totals['labeling_cost']), "Hyb/Wash/Stain/\nScan Charge" => fmt_dollars(set_totals['hybridization_cost']), "QC Cost" => fmt_dollars(set_totals['qc_cost']), "Other Cost" => fmt_dollars(set_totals['other_cost']), "Total Cost" => fmt_dollars(set_totals['total_cost'])} table.column_order = [ "Charge Set", "Budget/PO", "Chips", "Chip Charge", "Labeling Charge", "Hyb/Wash/Stain/\nScan Charge", "QC Cost", "Other Cost", "Total Cost" ] table.render_on(_pdf) ############### # DETAIL PAGES ############### for set in charge_sets _pdf.start_new_page # print heading and charge set / project info _pdf.font_size = 16 _pdf.text "\n" + SiteConfig.organization_name + "", :justification => :center _pdf.text "" + SiteConfig.facility_name + "\n", :justification => :center if FileTest.exists?("public/images/organization_logo.jpg") # add logo if one exists _pdf.add_image_from_file "public/images/organization_logo.jpg", 450, 685, 120 end _pdf.font_size = 10 _pdf.text "\n\n" + "Project: " + set.name if set.charge_method == "internal" _pdf.text "Org Key: " + set.budget + "\n" + "Budget Manager: " + set.budget_manager + "\n\n" + "Budget Manager Approval: _________________________________" else _pdf.text "P.O. Number: " + set.budget end _pdf.text "\n\n" # print charge table, if there are any charges charges = Charge.find(:all, :conditions => ["charge_set_id = ?", set.id], :order => "date ASC") total = 0; if charges.size > 0 table = PDF::SimpleTable.new table.width = 536 table.position = :right table.orientation = :left table.font_size = 8 table.heading_font_size = 8 for charge in charges line_total = charge.chip_cost + charge.labeling_cost + charge.hybridization_cost + charge.qc_cost + charge.other_cost total = total + line_total table.data << { "Date" => charge.date, "Description" => charge.description, "Chip Charge" => fmt_dollars(charge.chip_cost), "Labeling Charge" => fmt_dollars(charge.labeling_cost), "Hyb/Wash/Stain/\nScan Charge" => fmt_dollars(charge.hybridization_cost), "QC Cost" => fmt_dollars(charge.qc_cost), "Other Cost" => fmt_dollars(charge.other_cost), "Sample Total" => fmt_dollars(line_total) } end table.column_order = [ "Date", "Description", "Chip Charge", "Labeling Charge", "Hyb/Wash/Stain/\nScan Charge", "QC Cost", "Other Cost", "Sample Total" ] table.columns["Other Cost"] = PDF::SimpleTable::Column.new("Other Cost") { |col| col.width = 60 } table.columns["Sample Total"] = PDF::SimpleTable::Column.new("Sample Total") { |col| col.width = 60 } table.render_on(_pdf) end _pdf.text "\n\n" # totals table table = PDF::SimpleTable.new table.position = :right table.orientation = :left table.font_size = 8 table.heading_font_size = 8 table.data = [ { "name" => "TOTAL", "content" => "" + fmt_dollars(total).to_s + "" }] table.column_order = [ "name", "content" ] table.columns["name"] = PDF::SimpleTable::Column.new("name") { |col| col.width = 60 } table.columns["content"] = PDF::SimpleTable::Column.new("content") { |col| col.width = 60 } table.show_headings = false table.shade_rows = :none table.render_on(_pdf) end ######## # DONE! ######## pdf_file_name = "charges_" + period.name + ".pdf" send_data _pdf.render, :filename => pdf_file_name, :type => "application/pdf" end def excel @period = ChargePeriod.find(params[:id]) puts "VERSION: " + Excel::VERSION workbook_name = "#{RAILS_ROOT}/tmp/excel/charges_" + @period.name + ".xls" workbook = Excel.new(workbook_name) # doing each side individually, since :border => 1 is giving an error bordered = Format.new( :bottom => 1, :top => 1, :left => 1, :right => 1 ) bordered_bold = Format.new( :bottom => 1, :top => 1, :left => 1, :right => 1, :bold => true ) workbook.add_format(bordered) workbook.add_format(bordered_bold) ############### # SUMMARY PAGE ############### summary = workbook.add_worksheet("summary") current_row = 0 summary.write_row current_row+=1, 1, [ "Charge Set", "Budget/PO", "Chips", "Chip Charge", "Labeling Charge", "Hyb/Wash/Stain/\nScan Charge", "QC Cost", "Other Cost", "Total Cost" ], bordered charge_sets = ChargeSet.find(:all, :conditions => [ "charge_period_id = ?", @period.id ], :order => "name ASC") set_totals = Hash.new(0) for set in charge_sets totals = set.get_totals set_totals['chips'] += totals['chips'] set_totals['chip_cost'] += totals['chip_cost'] set_totals['labeling_cost'] += totals['labeling_cost'] set_totals['hybridization_cost'] += totals['hybridization_cost'] set_totals['qc_cost'] += totals['qc_cost'] set_totals['other_cost'] += totals['other_cost'] set_totals['total_cost'] += totals['total_cost'] summary.write_row current_row+=1, 1, [ set.name, set.budget, totals['chips'], fmt_dollars(totals['chip_cost']), fmt_dollars(totals['labeling_cost']), fmt_dollars(totals['hybridization_cost']), fmt_dollars(totals['qc_cost']), fmt_dollars(totals['other_cost']), fmt_dollars(totals['total_cost']) ], bordered end # totals summary.write_row current_row+=2, 2, [ "TOTALS", set_totals['chips'], fmt_dollars(set_totals['chip_cost']), fmt_dollars(set_totals['labeling_cost']), fmt_dollars(set_totals['hybridization_cost']),fmt_dollars(set_totals['qc_cost']), fmt_dollars(set_totals['other_cost']), fmt_dollars(set_totals['total_cost']) ], bordered_bold ############### # DETAIL PAGES ############### detail = Hash.new(0) for set in charge_sets detail[set.name] = workbook.add_worksheet(set.name) # print heading and charge set / project info row = 2 detail[set.name].write row+=1, 1, SiteConfig.organization_name detail[set.name].write row+=1, 1, SiteConfig.facility_name detail[set.name].write row+=3, 1, "Project: " + set.name if set.charge_method == "internal" detail[set.name].write row+=1, 1, "Org Key: " + set.budget detail[set.name].write row+=1, 1, "Budget Manager: " + set.budget_manager detail[set.name].write row+=1, 1, "Budget Manager Approval: _________________________________" else detail[set.name].write row+=1, 1, "P.O. Number: " + set.budget end # charge headings detail[set.name].write row+=3, 1, [ "Date", "Description", "Chip Charge", "Labeling Charge", "Hyb/Wash/Stain/\nScan Charge", "QC Cost", "Other Cost", "Sample Total" ], bordered # print line item charges charges = Charge.find(:all, :conditions => ["charge_set_id = ?", set.id], :order => "date ASC") total = 0; for charge in charges line_total = charge.chip_cost + charge.labeling_cost + charge.hybridization_cost + charge.qc_cost + charge.other_cost total = total + line_total detail[set.name].write row+=1, 1, [ charge.date.to_s, charge.description, fmt_dollars(charge.chip_cost), fmt_dollars(charge.labeling_cost), fmt_dollars(charge.hybridization_cost), fmt_dollars(charge.qc_cost), fmt_dollars(charge.other_cost), fmt_dollars(line_total) ], bordered end # totals detail[set.name].write row+=1, 7, [ "TOTAL", fmt_dollars(total) ], bordered_bold end workbook.close send_file workbook_name end private def fmt_dollars(amt) sprintf("$%0.2f", amt) end end