Skip to content

Commit a6559e5

Browse files
committed
merge cbarber
2 parents 6623af9 + e74941b commit a6559e5

File tree

8 files changed

+136
-1
lines changed

8 files changed

+136
-1
lines changed

Gemfile

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
group :test do
22
gem 'webrat'
33
end
4+
5+
gem 'riif'

app/controllers/timesheet_controller.rb

+12
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ def report
7878
respond_to do |format|
7979
format.html { render :action => 'details', :layout => false if request.xhr? }
8080
format.csv { send_data @timesheet.to_csv, :filename => 'timesheet.csv', :type => "text/csv" }
81+
format.iif {
82+
render(
83+
:iif => render_to_string(:locals => {
84+
:total => @total,
85+
:grand_total => @grand_total,
86+
:timesheet => @timesheet,
87+
:date_from => @timesheet.date_from.to_date,
88+
:date_to => @timesheet.date_to.to_date
89+
}),
90+
:filename => "timesheet-#{@timesheet.projects.collect{|p| p.id.to_s.rjust(3, '0')}.join('')}"
91+
)
92+
}
8193
end
8294
end
8395

app/helpers/timesheet_helper.rb

+27
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ def link_to_csv_export(timesheet)
3939
:class => 'icon icon-timesheet')
4040
end
4141

42+
def link_to_iif_export(timesheet)
43+
link_to('Quickbooks',
44+
{
45+
:controller => 'timesheet',
46+
:action => 'report',
47+
:format => 'iif',
48+
:timesheet => timesheet.to_param
49+
},
50+
:method => 'post',
51+
:class => 'icon icon-timesheet')
52+
end
53+
4254
def toggle_issue_arrows(issue_id)
4355
js = "toggleTimeEntries('#{issue_id}'); return false;"
4456

@@ -128,4 +140,19 @@ def user_options(timesheet)
128140
selected_users)
129141

130142
end
143+
144+
def options_for_period_select(value)
145+
options_for_select([[l(:label_all_time), 'all'],
146+
[l(:label_today), 'today'],
147+
[l(:label_yesterday), 'yesterday'],
148+
[l(:label_this_week), 'current_week'],
149+
[l(:label_last_week), 'last_week'],
150+
[l(:label_last_n_weeks, 2), 'last_2_weeks'],
151+
[l(:label_last_n_days, 7), '7_days'],
152+
[l(:label_this_month), 'current_month'],
153+
[l(:label_last_month), 'last_month'],
154+
[l(:label_last_n_days, 30), '30_days'],
155+
[l(:label_this_year), 'current_year']],
156+
value)
157+
end
131158
end

app/models/timesheet.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def to_param
150150

151151
def to_csv
152152
out = "";
153-
FCSV.generate(out, :encoding => 'u', :force_quotes => true) do |csv|
153+
CSV.generate(out, :encoding => 'u', :force_quotes => true) do |csv|
154154
csv << csv_header
155155

156156
# Write the CSV based on the group/sort

app/views/timesheet/report.html.erb

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<div class="contextual">
22
<%= link_to_csv_export(@timesheet) %>
3+
<%= link_to_iif_export(@timesheet) %>
34
<%= permalink_to_timesheet(@timesheet) %>
45
</div>
56

app/views/timesheet/report.iif.riif

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
iif.accnt do
2+
row do
3+
name 'Accounts Receivable'
4+
accnttype 'AR'
5+
end
6+
7+
row do
8+
name 'Service Income'
9+
accnttype 'INC'
10+
end
11+
end
12+
13+
iif.invitem do
14+
row do
15+
name 'website'
16+
invitemtype 'SERV'
17+
desc 'website'
18+
accnt 'Services'
19+
price '1'
20+
cost '0'
21+
taxable 'N'
22+
end
23+
end
24+
25+
iif.trns do |trns|
26+
trns.row do
27+
trnstype 'INVOICE'
28+
date Time.now.strftime("%m/%d/%Y")
29+
accnt 'Accounts Receivable'
30+
name 'Customer'
31+
amount -timesheet.time_entries.map { |project, data| data[:logs].inject(0) { |sum, time_entry| sum + time_entry.invoice_amount } }.sum
32+
docnum "#{date_from.year}-#{timesheet.projects.collect{|p| p.id.to_s.rjust(3, '0') }.join('')}-#{date_from.strftime('%m%d')}-#{date_to.strftime('%m%d')}"
33+
memo "Time entered for #{timesheet.time_entries.map { |project, data| project }.join(', ') } between #{date_from.strftime('%Y-%m-%d')} and #{date_to.strftime('%Y-%m-%d')}"
34+
clear 'N'
35+
toprint 'Y'
36+
# nameistaxable 'N' # doesn't exist in gem's dsl
37+
end
38+
39+
trns.spl do |spl|
40+
timesheet.time_entries.each do |project, data|
41+
data[:logs].each do |time_entry|
42+
spl.row do
43+
trnstype 'INVOICE'
44+
date time_entry.spent_on.strftime("%m/%d/%Y")
45+
accnt 'Service Income'
46+
amount time_entry.invoice_amount
47+
memo "#{time_entry.user.name} [#{time_entry.spent_on.strftime("%Y-%m-%d")}] ##{time_entry.issue.id} - #{time_entry.issue.subject}"
48+
clear 'N'
49+
qnty time_entry.invoice_quantity
50+
# TODO: Hardcoded the custom_field id for now since there isn't a nice getter from name
51+
price time_entry.invoice_price
52+
invitem 'website'
53+
taxable 'N'
54+
# yeartodate '0' # doesn't exist in gem's dsl
55+
# wagebase '0' # doesn't exist in gem's dsl
56+
end
57+
end
58+
end
59+
end
60+
end

init.rb

+2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
require_dependency 'project'
1414
require_dependency 'principal'
1515
require_dependency 'user'
16+
require_dependency 'time_entry'
1617
Project.send(:include, RedmineTimesheetPlugin::Patches::ProjectPatch)
1718
User.send(:include, RedmineTimesheetPlugin::Patches::UserPatch)
19+
TimeEntry.send(:include, RedmineTimesheetPlugin::Patches::TimeEntryPatch)
1820

1921
# Needed for the compatibility check
2022
begin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module RedmineTimesheetPlugin
2+
module Patches
3+
module TimeEntryPatch
4+
def self.included(base)
5+
base.extend(ClassMethods)
6+
7+
base.send(:include, InstanceMethods)
8+
base.class_eval do
9+
unloadable
10+
end
11+
end
12+
13+
module ClassMethods
14+
end
15+
16+
module InstanceMethods
17+
def invoice_amount
18+
invoice_price.value.to_i * invoice_quantity
19+
end
20+
21+
def invoice_quantity
22+
-hours
23+
end
24+
25+
def invoice_price
26+
project.custom_value_for(10)
27+
end
28+
end
29+
end
30+
end
31+
end

0 commit comments

Comments
 (0)