Compare commits
12 Commits
developmen
...
feature/lo
Author | SHA1 | Date |
---|---|---|
Bram Senders | b31cd03330 | |
Bram Senders | d706e91e9d | |
Bram Senders | 553a919cb1 | |
Bram Senders | 0ae19e3376 | |
Bram Senders | 1da6ca6e85 | |
Bram Senders | 2b4acbdd35 | |
Bram Senders | f8286ba862 | |
Bram Senders | 2926b30969 | |
Bram Senders | 803a8894dc | |
Bram Senders | f9836029c7 | |
Bram Senders | 1b00857d62 | |
Bram Senders | a4e42d9aca |
201
stoptime.rb
201
stoptime.rb
|
@ -156,6 +156,7 @@ module StopTime::Models
|
|||
# task.
|
||||
class TimeEntry < Base
|
||||
belongs_to :task
|
||||
belongs_to :location
|
||||
has_one :customer, :through => :task
|
||||
|
||||
# Returns the total amount of time, the duration, in hours.
|
||||
|
@ -170,6 +171,7 @@ module StopTime::Models
|
|||
# tasks and through the tasks registered time.
|
||||
class Invoice < Base
|
||||
has_many :tasks
|
||||
has_many :locations
|
||||
has_many :time_entries, :through => :tasks
|
||||
belongs_to :customer
|
||||
|
||||
|
@ -203,6 +205,22 @@ module StopTime::Models
|
|||
class CompanyInfo < Base
|
||||
end
|
||||
|
||||
# == The location class
|
||||
#
|
||||
# This class represents a specific location where work can be done.
|
||||
# Each location has a name, a distance (in kilometres, from the user's
|
||||
# home) and travel time (in minutes, also from the user's home). Each
|
||||
# time entry can be associated with a location.
|
||||
class Location < Base
|
||||
has_many :time_entries
|
||||
belongs_to :invoice
|
||||
|
||||
# Returns whether the location is billed, i.e. included in an invoice.
|
||||
def billed?
|
||||
not invoice.nil?
|
||||
end
|
||||
end
|
||||
|
||||
class StopTimeTables < V 1.0 # :nodoc:
|
||||
def self.up
|
||||
create_table Customer.table_name do |t|
|
||||
|
@ -341,6 +359,23 @@ module StopTime::Models
|
|||
end
|
||||
end
|
||||
|
||||
class LocationSupport < V 1.9 # :nodoc:
|
||||
def self.up
|
||||
create_table Location.table_name do |t|
|
||||
t.string :name
|
||||
t.float :distance, :travel_time
|
||||
t.integer :invoice_id
|
||||
t.timestamps
|
||||
end
|
||||
add_column(TimeEntry.table_name, :location_id, :integer)
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table Location.table_name
|
||||
remove_column(TimeEntry.table_name, :location_id)
|
||||
end
|
||||
end
|
||||
|
||||
end # StopTime::Models
|
||||
|
||||
# = The Stop… Camping Time! controllers
|
||||
|
@ -792,6 +827,9 @@ module StopTime::Controllers
|
|||
@task_list = Task.all.reject { |t| t.billed? }.map do |t|
|
||||
[t.id, t.name]
|
||||
end
|
||||
@location_list = Location.all.reject { |l| l.billed? }.map do |l|
|
||||
[l.id, l.name]
|
||||
end
|
||||
@input["bill"] = true # Bill by default.
|
||||
render :time_entries
|
||||
end
|
||||
|
@ -802,6 +840,7 @@ module StopTime::Controllers
|
|||
if @input.has_key? "enter"
|
||||
@time_entry = TimeEntry.create(
|
||||
:task_id => @input.task,
|
||||
:location_id => @input.location,
|
||||
:date => @input.date,
|
||||
:start => "#{@input.date} #{@input.start}",
|
||||
:end => "#{@input.date} #{@input.end}",
|
||||
|
@ -858,6 +897,7 @@ module StopTime::Controllers
|
|||
@input = @time_entry.attributes
|
||||
@input["customer"] = @time_entry.task.customer.id
|
||||
@input["task"] = @time_entry.task.id
|
||||
@input["location"] = @time_entry.location.id
|
||||
@input["date"] = @time_entry.date.to_date
|
||||
@input["start"] = @time_entry.start.to_formatted_s(:time_only)
|
||||
@input["end"] = @time_entry.end.to_formatted_s(:time_only)
|
||||
|
@ -890,6 +930,7 @@ module StopTime::Controllers
|
|||
@time_entry.start = "#{@input["date"]} #{@input["start"]}"
|
||||
@time_entry.end = "#{@input["date"]} #{@input["end"]}"
|
||||
@time_entry.task = Task.find(@input.task)
|
||||
@time_entry.location = Location.find(@input.location)
|
||||
@time_entry.bill = @input.has_key? "bill"
|
||||
@time_entry.save
|
||||
if @time_entry.invalid?
|
||||
|
@ -975,6 +1016,102 @@ module StopTime::Controllers
|
|||
end
|
||||
end
|
||||
|
||||
# == The locations controller
|
||||
#
|
||||
# Controller for viewing a list of existing locations or creating a new
|
||||
# one.
|
||||
#
|
||||
# path:: /locations
|
||||
# view:: Views#locations and Views#location_form
|
||||
class Locations
|
||||
# Gets the list of locations and displays them via Views#locations.
|
||||
def get
|
||||
@locations = Location.all
|
||||
render :locations
|
||||
end
|
||||
|
||||
# Creates a new location object (Models::Location) if the input is
|
||||
# valid and redirects to LocationsN.
|
||||
# If the provided information is invalid, the errors are retrieved
|
||||
# and shown in the initial form (Views#location_form).
|
||||
def post
|
||||
return redirect R(Locations) if @input.cancel
|
||||
@location = Location.create(
|
||||
:name => @input.name,
|
||||
:distance => @input.distance,
|
||||
:travel_time => @input.travel_time)
|
||||
@location.save
|
||||
if @location.invalid?
|
||||
@errors = @location.errors
|
||||
@target = [Location]
|
||||
@button = "create"
|
||||
return render :location_form
|
||||
end
|
||||
redirect R(LocationsN, @location.id)
|
||||
end
|
||||
end
|
||||
|
||||
# == The location creation controller
|
||||
#
|
||||
# Controller for filling in the information to create a new location.
|
||||
#
|
||||
# path:: /locations/new
|
||||
# view:: Views#location_form
|
||||
class LocationsNew
|
||||
# Generates the form to create a new location object
|
||||
# (Models::Location) using Views#location_form.
|
||||
def get
|
||||
@location = Location.new
|
||||
@input = @location.attributes
|
||||
|
||||
@target = [Locations]
|
||||
@button = "create"
|
||||
render :location_form
|
||||
end
|
||||
end
|
||||
|
||||
# == The location controller
|
||||
#
|
||||
# Controller for viewing and updating information of a location.
|
||||
#
|
||||
# path:: /locations/_location_id_
|
||||
# view:: Views#location_form
|
||||
class LocationsN
|
||||
# Finds the specific location for the given _location_id_ and shows
|
||||
# a form for updating via Views#location_form.
|
||||
def get(location_id)
|
||||
@location = Location.find(location_id)
|
||||
@input = @location.attributes
|
||||
|
||||
@target = [LocationsN, @location.id]
|
||||
@button = "update"
|
||||
render :location_form
|
||||
end
|
||||
|
||||
# Updates or deletes the location with the given _location_id_ if the
|
||||
# input is valid and redirects to LocationsN.
|
||||
# If the provided information is invalid, the errors are retrieved
|
||||
# and shown in the initial form (Views#location_form).
|
||||
def post(location_id)
|
||||
return redirect R(Locations) if @input.cancel
|
||||
@location = Location.find(location_id)
|
||||
if @input.has_key? "delete"
|
||||
@location.delete
|
||||
elsif @input.has_key? "update"
|
||||
attrs = ["name", "distance", "travel_time"]
|
||||
attrs.each do |attr|
|
||||
@location[attr] = @input[attr]
|
||||
end
|
||||
@location.save
|
||||
if @location.invalid?
|
||||
@errors = @location.errors
|
||||
return render :location_form
|
||||
end
|
||||
end
|
||||
redirect R(Locations)
|
||||
end
|
||||
end
|
||||
|
||||
# == The static data controller
|
||||
#
|
||||
# Controller for serving static data information available in the
|
||||
|
@ -1031,7 +1168,8 @@ module StopTime::Views
|
|||
["Timeline", Timeline],
|
||||
["Customers", Customers],
|
||||
["Invoices", Invoices],
|
||||
["Company", Company]].each { |label, ctrl| _menu_link(label, ctrl) }
|
||||
["Company", Company],
|
||||
["Locations", Locations]].each { |label, ctrl| _menu_link(label, ctrl) }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1095,6 +1233,7 @@ module StopTime::Views
|
|||
h2 "Timeline"
|
||||
table.timeline do
|
||||
col.task {}
|
||||
col.location {}
|
||||
col.date {}
|
||||
col.start_time {}
|
||||
col.end_time {}
|
||||
|
@ -1103,6 +1242,7 @@ module StopTime::Views
|
|||
col.flag {}
|
||||
tr do
|
||||
th "Project/Task"
|
||||
th "Location"
|
||||
th "Date"
|
||||
th "Start time"
|
||||
th "End time"
|
||||
|
@ -1113,6 +1253,7 @@ module StopTime::Views
|
|||
form :action => R(Timeline), :method => :post do
|
||||
tr do
|
||||
td { _form_select("task", @task_list) }
|
||||
td { _form_select("location", @location_list) }
|
||||
td { input :type => :text, :name => "date",
|
||||
:value => DateTime.now.to_date.to_formatted_s }
|
||||
td { input :type => :text, :name => "start",
|
||||
|
@ -1131,6 +1272,12 @@ module StopTime::Views
|
|||
tr do
|
||||
td { a entry.task.name,
|
||||
:href => R(CustomersNTasksN, entry.customer.id, entry.task.id) }
|
||||
if entry.location
|
||||
td { a entry.location.name,
|
||||
:href => R(LocationsN, entry.location.id) }
|
||||
else
|
||||
td { "unspecified" }
|
||||
end
|
||||
td { a entry.date.to_date,
|
||||
:href => R(TimelineN, entry.id) }
|
||||
td { entry.start.to_formatted_s(:time_only) }
|
||||
|
@ -1564,6 +1711,58 @@ module StopTime::Views
|
|||
end
|
||||
end
|
||||
|
||||
# The main overview of the list of locations.
|
||||
def locations
|
||||
h2 "Locations"
|
||||
if @locations.empty?
|
||||
p do
|
||||
text "None found! You can create one "
|
||||
a "here", :href => R(LocationsNew)
|
||||
text "."
|
||||
end
|
||||
else
|
||||
table.locations do
|
||||
col.name {}
|
||||
col.distance {}
|
||||
col.travel_time {}
|
||||
tr do
|
||||
th "Name"
|
||||
th "Distance (km)"
|
||||
th "Travel time (min)"
|
||||
end
|
||||
@locations.each do |location|
|
||||
tr do
|
||||
td { a location.name, :href => R(LocationsN, location.id) }
|
||||
td { location.distance }
|
||||
td { location.travel_time }
|
||||
td do
|
||||
form :action => R(LocationsN, location.id), :method => :post do
|
||||
input :type => :submit, :name => "delete", :value => "Delete"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
a "Add a new location", :href => R(LocationsNew)
|
||||
end
|
||||
end
|
||||
|
||||
# Form for editing the properties of a location (Models::Location)
|
||||
def location_form
|
||||
form.float_left :action => R(*@target), :method => :post do
|
||||
h2 "Location Information"
|
||||
ol do
|
||||
li { _form_input_with_label("Name", "name", :text) }
|
||||
li { _form_input_with_label("Distance (km)", "distance", :text) }
|
||||
li { _form_input_with_label("Travel time (min)", "travel_time", :text) }
|
||||
end
|
||||
input :type => "submit", :name => @button, :value => @button.capitalize
|
||||
input :type => "submit", :name => "cancel", :value => "Cancel"
|
||||
end
|
||||
div.clear {}
|
||||
end
|
||||
|
||||
# Partial view that generates a form label with the given _label_name_
|
||||
# and a form input with the given _input_name_ and _type_, such that the
|
||||
# label is linked to the input.
|
||||
|
|
Loading…
Reference in New Issue