From 06c25d66c901f7b5c7357b5fe07de4b124ff673b Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Wed, 26 Jun 2013 20:23:03 +0200 Subject: [PATCH 01/24] Move add customer button to the header --- stoptime.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index 2ae3e31..d7f0caf 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -1691,7 +1691,12 @@ module StopTime::Views # The main overview of the list of customers. def customers header.page_header do - h1 "Customers" + h1 do + text! "Customers" + div.btn_group.pull_right do + a.btn.btn_small "» Add a new customer", :href=> R(CustomersNew) + end + end end if @customers.empty? p do @@ -1755,7 +1760,6 @@ module StopTime::Views end end end - a.btn "» Add a new customer", :href=> R(CustomersNew) end end From 073bf11beff9cdce9d3c0bbc986fc10228faa989 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Wed, 26 Jun 2013 20:23:56 +0200 Subject: [PATCH 02/24] Rework the project/task list in the customer_form view (closes: #9a33e4) --- stoptime.rb | 96 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index d7f0caf..d1d81c5 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -795,6 +795,20 @@ module StopTime::Controllers @customer = Customer.find(customer_id) @input = @customer.attributes @tasks = @customer.tasks.all(:order => "name, invoice_id ASC") + # FIXME: this dirty hack assumes that tasks have unique names, + # becasue there is no reference from billed tasks to its original + # task. + @billed_tasks = {} + cur_active_task = nil + @tasks.each do |task| + if task.billed? + @billed_tasks[cur_active_task] << task + else + cur_active_task = task + @billed_tasks[task] = [] + end + end + @invoices = @customer.invoices @invoices.each do |i| @input["paid_#{i.number}"] = true if i.paid? @@ -1797,27 +1811,75 @@ module StopTime::Views div.span6 do if @edit_task - h2 "Projects & Tasks" - # FXIME: the following is not very RESTful! - form :action => R(CustomersNTasks, @customer.id), :method => :post do - select.input_xlarge :name => "task_id", :size => 10 do - @tasks.each do |task| - if task.billed? - option(:value => task.id) { task.name + " (#{task.invoice.number})" } - else - option(:value => task.id) { task.name } + h2 do + text! "Projects & Tasks" + div.btn_group.pull_right do + a.btn.btn_small "» Add a new project/task", + :href => R(CustomersNTasksNew, @customer.id) + end + end + div.accordion.task_list! do + @billed_tasks.keys.sort_by { |task| task.name }.each do |task| + div.accordion_group do + div.accordion_heading do + span.accordion_toggle do + a task.name, "data-toggle" => "collapse", + "data-parent" => "#task_list", + :href => "#collapse#{task.id}" + # FXIME: the following is not very RESTful! + form.form_inline.pull_right :action => R(CustomersNTasks, @customer.id), + :method => :post do + a.btn.btn_mini "Edit", :href => R(CustomersNTasksN, @customer.id, task.id) + input :type => :hidden, :name => "task_id", :value => task.id + button.btn.btn_danger.btn_mini "Delete", :type => :submit, + :name => "delete", :value => "Delete" + end + end + end + div.accordion_body.collapse :id => "collapse#{task.id}" do + div.accordion_inner do + if @billed_tasks[task].empty? + i { "No billed projects/tasks found" } + else + table.table.table_condensed do + col.task_list + @billed_tasks[task].each do |billed_task| + tr do + td do + a billed_task.comment_or_name, + :href => R(CustomersNTasksN, @customer.id, billed_task.id) + small do + text! "(billed in invoice " + a billed_task.invoice.number, + :title => billed_task.invoice.number, + :href => R(CustomersNInvoicesX, @customer.id, + billed_task.invoice.number) + text! ")" + end + end + td do + # FXIME: the following is not very RESTful! + form.form_inline.pull_right :action => R(CustomersNTasks, @customer.id), + :method => :post do + a.btn.btn_mini "Edit", + :href => R(CustomersNTasksN, @customer.id, + billed_task.id) + input :type => :hidden, :name => "task_id", + :value => billed_task.id + button.btn.btn_danger.btn_mini "Delete", :type => :submit, + :name => "delete", :value => "Delete" + end + end + end + end + end + end + end end end end - div.form_actions do - button.btn.btn_primary "Edit", :type => :submit, - :name => "edit", :value => "Edit" - button.btn.btn_danger "Delete", :type => :submit, - :name => "delete", :value => "Delete" - a.btn "» Add a new project/task", - :href => R(CustomersNTasksNew, @customer.id) - end end + h2 "Invoices" _invoice_list(@invoices) a.btn "» Create a new invoice", From 43e862d5de7e5211a7716c7d3fe96a5a62825632 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Wed, 26 Jun 2013 20:45:46 +0200 Subject: [PATCH 03/24] Tweak the width of the task list table in the customer_form view --- templates/sass/style.sass | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/sass/style.sass b/templates/sass/style.sass index c837c1a..862547f 100644 --- a/templates/sass/style.sass +++ b/templates/sass/style.sass @@ -48,6 +48,8 @@ table width: 250px col.email, col.period width: 170px + col.task_list + width: 330px col.number width: 70px From 62dfd04776babf780abffcf49c47a2fdc2eb88e6 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Wed, 26 Jun 2013 20:46:27 +0200 Subject: [PATCH 04/24] Replace the label hack in grouped select forms by a decent optgroup --- stoptime.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index d1d81c5..6d71a7e 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -2483,12 +2483,13 @@ module StopTime::Views html_options.merge!(:name => name, :id => name) select(html_options) do opts.keys.sort.each do |key| - option("— #{key} —", {:disabled => true}) - opts[key].sort_by { |o| o.last }.each do |opt_val, opt_str| - if @input[name] == opt_val - option(opt_str, {:value => opt_val, :selected => true}) - else - option(opt_str, {:value => opt_val}) + optgroup :label => key do + opts[key].sort_by { |o| o.last }.each do |opt_val, opt_str| + if @input[name] == opt_val + option(opt_str, {:value => opt_val, :selected => true}) + else + option(opt_str, {:value => opt_val}) + end end end end From 33e5d047a0d4f515f393435df2445713b8bce5db Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Wed, 26 Jun 2013 20:47:09 +0200 Subject: [PATCH 05/24] Make the time_entry_form view also use a nested customer/task selector --- stoptime.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index 6d71a7e..407cdcb 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -1261,7 +1261,10 @@ module StopTime::Controllers # registering time. def get @customer_list = Customer.all.map { |c| [c.id, c.shortest_name] } - @task_list = Task.all.reject { |t| t.billed? }.map { |t| [t.id, t.name] } + @task_list = Hash.new { |h, k| h[k] = Array.new } + Task.all.reject { |t| t.billed? }.each do |t| + @task_list[t.customer.shortest_name] << [t.id, t.name] + end @input["bill"] = true @input["date"] = DateTime.now.to_date @input["start"] = Time.now.to_formatted_s(:time_only) @@ -1290,9 +1293,10 @@ module StopTime::Controllers @input["start"] = @time_entry.start.to_formatted_s(:time_only) @input["end"] = @time_entry.end.to_formatted_s(:time_only) @customer_list = Customer.all.map { |c| [c.id, c.shortest_name] } - @task_list = Task.all(:order => "name, invoice_id ASC").map do |t| + @task_list = Hash.new { |h, k| h[k] = Array.new } + Task.all(:order => "name, invoice_id ASC").each do |t| name = t.billed? ? t.name + " (#{t.invoice.number})" : t.name - [t.id, name] + @task_list[t.customer.shortest_name] << [t.id, name] end @target = [TimelineN, entry_id] @@ -1669,7 +1673,7 @@ module StopTime::Views div.control_group do label.control_label "Task", :for => "task" div.controls do - _form_select("task", @task_list) + _form_select_nested("task", @task_list) end end if @time_entry.present? and @time_entry.task.billed? From 17278fac989bdaf68b1b55053a604af223f05e2b Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:31:41 +0200 Subject: [PATCH 06/24] Add specification related attributes to the Customer and Invoice model --- stoptime.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/stoptime.rb b/stoptime.rb index 407cdcb..c10847c 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -193,6 +193,7 @@ module StopTime::Models # [email] email address (String) # [phone] phone number (String) # [hourly_rate] default hourly rate (Float) + # [time_specification] whether the customer requires time specifications (TrueClass/FalseClass) # [created_at] time of creation (Time) # [updated_at] time of last update (Time) # @@ -358,6 +359,8 @@ module StopTime::Models # [id] unique identification number (Fixnum) # [number] invoice number (Fixnum) # [paid] flag whether the invoice has been paid (TrueClass/FalseClass) + # [include_specification] flag whether the invoice should include a time + # specification (TrueClass/FalseClass) # [created_at] time of creation (Time) # [updated_at] time of last update (Time) # @@ -694,6 +697,18 @@ module StopTime::Models end end + class TimeSpecificationSupport < V 1.95 # :nodoc: + def self.up + add_column(Customer.table_name, :time_specification, :boolean) + add_column(Invoice.table_name, :include_specification, :boolean) + end + + def self.down + remove_column(Customer.table_name, :time_specification) + remove_column(Invoice.table_name, :include_specification) + end + end + end # StopTime::Models # = The Stop… Camping Time! controllers From 7a58ae93316a14ac8ec23ec8f6b7f40b841d6392 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:32:27 +0200 Subject: [PATCH 07/24] Add the time specification to the customer_form view; update it If time specifications are enabled for a customer this is considered to be a global setting for invoices related to this customer. Note that it will note change any of the existing voices, it will only affect newly created ones! --- stoptime.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/stoptime.rb b/stoptime.rb index c10847c..6f02fcb 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -851,6 +851,7 @@ module StopTime::Controllers attrs.each do |attr| @customer[attr] = @input[attr] end + @customer.time_specification = @input.has_key? "time_specification" @customer.save if @customer.invalid? @errors = @customer.errors @@ -1819,6 +1820,12 @@ module StopTime::Views _form_input_with_label("Phone number", "phone", :tel) _form_input_with_label("Financial contact", "financial_contact", :text) _form_input_with_label("Default hourly rate", "hourly_rate", :text) + div.control_group do + label.control_label "Time specifications?" + div.controls do + _form_input_checkbox("time_specification") + end + end div.form_actions do button.btn.btn_primary @button.capitalize, :type => "submit", :name => @button, :value => @button.capitalize From afd037b95e26bb063a6ac94cfcbcc49f59f239c7 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:32:45 +0200 Subject: [PATCH 08/24] Add the time specification to the invoice_form view; update it Generation of a time specification appendix can be enabled for each invoice indepently on whether it is or is not enabled for the customer. However, whether it is enabled by default when an invoice is created, that does follow the setting for the customer. --- stoptime.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stoptime.rb b/stoptime.rb index 6f02fcb..ebe0c78 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -1056,6 +1056,7 @@ module StopTime::Controllers invoice = Invoice.create(:number => number) invoice.customer = Customer.find(customer_id) invoice.company_info = CompanyInfo.last + invoice.include_specification = invoice.customer.time_specification # Handle the hourly rated tasks first by looking at the selected time # entries. @@ -1143,6 +1144,7 @@ module StopTime::Controllers def post(customer_id, invoice_number) invoice = Invoice.find_by_number(invoice_number) invoice.paid = @input.has_key? "paid" + invoice.include_specification = @input.has_key? "include_specification" invoice.save redirect R(CustomersNInvoicesX, customer_id, invoice_number) @@ -2040,6 +2042,12 @@ module StopTime::Views _form_input_checkbox("paid") end end + div.control_group do + label.control_label "Include specification?" + div.controls do + _form_input_checkbox("include_specification") + end + end div.form_actions do button.btn.btn_primary "Update", :type => :submit, :name => "update", :value => "Update" From 6fc2cb87b3aed03465ad41ac9117249273e438d8 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:33:09 +0200 Subject: [PATCH 09/24] Remove 12pt default for the invoice template --- templates/invoice.tex.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/invoice.tex.erb b/templates/invoice.tex.erb index cdc2692..38f6fb4 100644 --- a/templates/invoice.tex.erb +++ b/templates/invoice.tex.erb @@ -1,4 +1,4 @@ -\documentclass[a4paper,12pt,oneside,dutch]{isodoc} +\documentclass[a4paper,oneside,dutch]{isodoc} % rubber: clean <%= @number %>.out From 66c46cd7c33f48ea31cc326f1505fdb7837b0aba Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:34:04 +0200 Subject: [PATCH 10/24] Generate a specification on a new page if enabled for the invoice --- templates/invoice.tex.erb | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/templates/invoice.tex.erb b/templates/invoice.tex.erb index 38f6fb4..f6befaf 100644 --- a/templates/invoice.tex.erb +++ b/templates/invoice.tex.erb @@ -88,6 +88,13 @@ \newcommand{\ihtotal}[1]{\cmidrule[.05em]{4-4}% \textbf{\totaltext}&&&\textbf{\currency~#1}} +\newenvironment{istable}% + {\vskip1em\tabularx{\linewidth}{@{}X@{\quad}l@{\qquad}r@{}} + \descriptiontext&Datum&Aantal uur\ML}% + {\endtabularx} +\newcommand{\istask}[1]{\textbf{#1}\\} +\newcommand{\isitem}[3]{\quad #1\\} + \begin{document} \invoice{ @@ -128,4 +135,26 @@ \accountdata } +<% if @invoice.include_specification? %>{ + \newpage + + {\bfseries\scshape\Large Specificatie} + + Hieronder volgt een specificatie van gemaakte uren per taak per + uitgevoerde activiteit. + + \begin{istable} + <% @invoice.tasks.each do |task| +%> \istask{<%= task.comment_or_name %>}<% + task.time_entries.each do |time_entry| %> + \isitem{<%= time_entry.comment || "Geen opmerking" %>}% + {<%= time_entry.date.to_date %>}% + {<%= number_with_precision(time_entry.hours_total) %>}<% + end %>\\[\medskipamount]<% + end %> + \end{istable} + \label{LastPageOf\thelettercount} +<% end %>} +\letter{} + \end{document} From 52d41145508c5bf8b67a70a5e8031b9a3329d570 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:34:27 +0200 Subject: [PATCH 11/24] Tweak paragraph spacing a bit (needed in the specification part) --- templates/invoice.tex.erb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/invoice.tex.erb b/templates/invoice.tex.erb index f6befaf..cfa3e37 100644 --- a/templates/invoice.tex.erb +++ b/templates/invoice.tex.erb @@ -61,6 +61,8 @@ <% end %><% unless @company.vatno.blank? %> vatno=<%= @company.vatno %>, <% end %><% unless @company.chamber.blank? %> chamber=<%= @company.chamber %> <% end %>} +\setlength{\parindent}{0pt} +\setlength{\parskip}{\medskipamount} <% if @company.bank_name.present? %> \renewcommand{\accountnotext}{<%= @company.bank_name %> rekeningnr} From 6fca2cdd6ece0a8a02487015b1b1acef0ec87c08 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:34:56 +0200 Subject: [PATCH 12/24] Add a reference to the accompanying specification if enabled on the 1st page --- templates/invoice.tex.erb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/invoice.tex.erb b/templates/invoice.tex.erb index cfa3e37..aacabee 100644 --- a/templates/invoice.tex.erb +++ b/templates/invoice.tex.erb @@ -131,6 +131,8 @@ \end{ihtable} \vspace{2em} +<% if @invoice.include_specification? +%> Zie bijlage op de volgende pagina voor een nadere specificatie.\\[1em]<%end %> Ik verzoek u vriendelijk het verschuldigde bedrag binnen 30 dagen na factuurdatum over te maken onder vermelding van het factuurnummer. \\ From 9e5ade6eb9071a98c23972e0bc9a5f337ec80f2a Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:49:41 +0200 Subject: [PATCH 13/24] Small refactoring --- stoptime.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index ebe0c78..2373f2f 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -1646,11 +1646,11 @@ module StopTime::Views td { entry.date.to_date } td { entry.start.to_formatted_s(:time_only) } td { entry.end.to_formatted_s(:time_only)} - if entry.comment.nil? or entry.comment.empty? - td { a(:href => R(TimelineN, entry.id)){ i "None" } } - else + if entry.comment.present? td { a entry.comment, :href => R(TimelineN, entry.id), :title => entry.comment } + else + td { a(:href => R(TimelineN, entry.id)){ i "None" } } end td { "%.2fh" % entry.hours_total } td do From 368592356c185320b12aa1d49cca4a3298f6d41a Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 13 Jul 2013 22:49:56 +0200 Subject: [PATCH 14/24] Add also links to time entries in the invoice_form view --- stoptime.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index 2373f2f..a9f1620 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -2095,9 +2095,10 @@ module StopTime::Views tr do td.indent do if entry.comment.present? - "• #{entry.comment}" + a "• #{entry.comment}", :href => R(TimelineN, entry.id), + :title => entry.comment else - em.light "• no comment" + a :href => R(TimelineN, entry.id) { i "• None" } end end td.text_right { "%.2fh" % entry.hours_total } From de58a979c8bce20182295c2f7f43bb79d30a7265 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sun, 14 Jul 2013 14:04:51 +0200 Subject: [PATCH 15/24] Fix syntax error in case of no time specification; remove \letter call --- templates/invoice.tex.erb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/templates/invoice.tex.erb b/templates/invoice.tex.erb index aacabee..54e3d39 100644 --- a/templates/invoice.tex.erb +++ b/templates/invoice.tex.erb @@ -158,7 +158,6 @@ end %> \end{istable} \label{LastPageOf\thelettercount} -<% end %>} -\letter{} +}<% end %> \end{document} From 47fca9df2a931341ab18e3c90887a9031523a8d9 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sun, 14 Jul 2013 14:32:02 +0200 Subject: [PATCH 16/24] Handle billed fixed-cost tasks correctly in the customer_form view Billed fixed-cost tasks will have no active task once they are billed, because invoicing a fixed-cost will not split off a task but manipulate the active one into being billed. --- stoptime.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/stoptime.rb b/stoptime.rb index a9f1620..490c4ec 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -817,7 +817,13 @@ module StopTime::Controllers cur_active_task = nil @tasks.each do |task| if task.billed? - @billed_tasks[cur_active_task] << task + if cur_active_task.nil? + # Apparently there is no active task anymore, probably + # it was a fixed-cost task + @billed_tasks[task] = [] + else + @billed_tasks[cur_active_task] << task + end else cur_active_task = task @billed_tasks[task] = [] From 19d4efaca3bc3035a43f4afe15f0bc9adea0147c Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sun, 14 Jul 2013 14:33:12 +0200 Subject: [PATCH 17/24] Indentation fixes --- stoptime.rb | 54 ++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index 490c4ec..c6619b2 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -1877,34 +1877,34 @@ module StopTime::Views else table.table.table_condensed do col.task_list - @billed_tasks[task].each do |billed_task| - tr do - td do - a billed_task.comment_or_name, - :href => R(CustomersNTasksN, @customer.id, billed_task.id) - small do - text! "(billed in invoice " - a billed_task.invoice.number, - :title => billed_task.invoice.number, - :href => R(CustomersNInvoicesX, @customer.id, - billed_task.invoice.number) - text! ")" + @billed_tasks[task].sort_by { |t| t.invoice.number }.each do |billed_task| + tr do + td do + a billed_task.comment_or_name, + :href => R(CustomersNTasksN, @customer.id, billed_task.id) + small do + text! "(billed in invoice " + a billed_task.invoice.number, + :title => billed_task.invoice.number, + :href => R(CustomersNInvoicesX, @customer.id, + billed_task.invoice.number) + text! ")" + end + end + td do + # FXIME: the following is not very RESTful! + form.form_inline.pull_right :action => R(CustomersNTasks, @customer.id), + :method => :post do + a.btn.btn_mini "Edit", + :href => R(CustomersNTasksN, @customer.id, + billed_task.id) + input :type => :hidden, :name => "task_id", + :value => billed_task.id + button.btn.btn_danger.btn_mini "Delete", :type => :submit, + :name => "delete", :value => "Delete" + end + end end - end - td do - # FXIME: the following is not very RESTful! - form.form_inline.pull_right :action => R(CustomersNTasks, @customer.id), - :method => :post do - a.btn.btn_mini "Edit", - :href => R(CustomersNTasksN, @customer.id, - billed_task.id) - input :type => :hidden, :name => "task_id", - :value => billed_task.id - button.btn.btn_danger.btn_mini "Delete", :type => :submit, - :name => "delete", :value => "Delete" - end - end - end end end end From 30fd5ec599fead0eb0723a9694040ef8543a41cd Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sun, 14 Jul 2013 14:37:40 +0200 Subject: [PATCH 18/24] Show a billed fixed-task under itself in the customer_form view As billed fixed-cost tasks cannot have an active task, the task itself still is the one that is billed. Show the task under itself to expose the fact that it is billed and in which invoice. --- stoptime.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stoptime.rb b/stoptime.rb index c6619b2..0c34401 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -820,7 +820,7 @@ module StopTime::Controllers if cur_active_task.nil? # Apparently there is no active task anymore, probably # it was a fixed-cost task - @billed_tasks[task] = [] + @billed_tasks[task] = [task] else @billed_tasks[cur_active_task] << task end From 7fcce379035e06aa5d56a39af9b50dc4f74afab3 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Fri, 4 Oct 2013 21:38:42 +0200 Subject: [PATCH 19/24] Fix the invoice template to show IBAN/BIC (closes: #688d33) If IBAN/BIC is set, it is shown instead of the normal account number. SEPA solves the problem that needs IBAN/BIC is conditionally shown (which is not possible). --- templates/invoice.tex.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/invoice.tex.erb b/templates/invoice.tex.erb index 54e3d39..136d561 100644 --- a/templates/invoice.tex.erb +++ b/templates/invoice.tex.erb @@ -56,8 +56,8 @@ term=30, accountno=<%= @company.accountno %>, accountname=<%= @company.accountname %>, -<% unless @company.accountiban.blank? %> iban=<% @company.accountiban %>, -<% end %><% unless @company.bank_bic.blank? %> bic=<% @company.bank_bic %>, +<% unless @company.accountiban.blank? %> iban=<%= @company.accountiban %>, +<% end %><% unless @company.bank_bic.blank? %> bic=<%= @company.bank_bic %>, <% end %><% unless @company.vatno.blank? %> vatno=<%= @company.vatno %>, <% end %><% unless @company.chamber.blank? %> chamber=<%= @company.chamber %> <% end %>} From 0f7c7311245dcd78b40d9032677a1ceed672175c Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Sat, 12 Oct 2013 11:15:29 +0200 Subject: [PATCH 20/24] Isodoc >= 1.00 is needed to have IBAN/BIC in the invoices --- README.rdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rdoc b/README.rdoc index cc27350..c262876 100644 --- a/README.rdoc +++ b/README.rdoc @@ -34,7 +34,7 @@ The following Ruby libraries are required: and the following LaTeX programs: * pdflatex, with: - * isodoc package + * isodoc package (>= 1.00) * rubber == Installation From 70c0ad4a543e0ba36a68ed124d7fcf04a4957cff Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Fri, 7 Feb 2014 20:30:38 +0100 Subject: [PATCH 21/24] Fix fixed cost tasks being grouped under random projects in customer view --- stoptime.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/stoptime.rb b/stoptime.rb index 0c34401..64ec42c 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -817,9 +817,11 @@ module StopTime::Controllers cur_active_task = nil @tasks.each do |task| if task.billed? - if cur_active_task.nil? - # Apparently there is no active task anymore, probably - # it was a fixed-cost task + if cur_active_task.nil? or + task.name != cur_active_task.name + # Apparently, this is billed but it does not belong to the + # current active task, so probably it was a fixed-cost task + cur_active_task = task @billed_tasks[task] = [task] else @billed_tasks[cur_active_task] << task From 25b052e864244170058f59578964012e9dfe725a Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Fri, 7 Feb 2014 21:04:08 +0100 Subject: [PATCH 22/24] Support alternative invoice template configuration --- config.yaml.example | 3 +++ stoptime.rb | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config.yaml.example b/config.yaml.example index 687778f..e2311be 100644 --- a/config.yaml.example +++ b/config.yaml.example @@ -8,3 +8,6 @@ # The invoice ID format (see strftime(3) and %N for the sequence number) #invoice_id: %Y%N + +# The invoice template used (without the .tex.erb suffix) +#invoice_template: invoice diff --git a/stoptime.rb b/stoptime.rb index 64ec42c..278dd3d 100644 --- a/stoptime.rb +++ b/stoptime.rb @@ -137,9 +137,10 @@ module StopTime::Models # The default configuration. Note that the configuration of the root # will be merged with this configuration. - DefaultConfig = { "invoice_id" => "%Y%N", - "hourly_rate" => 20.0, - "vat_rate" => 21.0 } + DefaultConfig = { "invoice_id" => "%Y%N", + "invoice_template" => "invoice", + "hourly_rate" => 20.0, + "vat_rate" => 21.0 } # Creates a new configuration object and loads the configuation. # by reading the file @config.yaml@ on disk, parsing it, and @@ -1165,7 +1166,7 @@ module StopTime::Controllers # Generates a LaTex document for the invoice with the given _number_. def _generate_invoice_tex(number) - template = TEMPLATE_DIR + "invoice.tex.erb" + template = TEMPLATE_DIR + "#{@config["invoice_template"]}.tex.erb" tex_file = PUBLIC_DIR + "invoices/#{number}.tex" I18n.with_locale :nl do @@ -1173,7 +1174,7 @@ module StopTime::Controllers File.open(tex_file, "w") { |f| f.write(erb.result(binding)) } end rescue Exception => err - tex_file.delete + tex_file.delete if File.exist? tex_file raise err end From 3dd4730afeffbf718bbd95b3afa8fae17ed82db4 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Fri, 7 Feb 2014 21:05:16 +0100 Subject: [PATCH 23/24] Ignore custom templates --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a12f568..7763e5a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ db/* public/invoices/*.pdf public/invoices/*.tex public/stylesheets/style.css +templates/*_invoice.tex.erb tmp/* From 407126d9a6ca059296d1ac34eb1a13f77f9236e3 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Fri, 7 Feb 2014 21:12:48 +0100 Subject: [PATCH 24/24] No longer include the BBAN number in the invoice template As per February, BBAN numbers are no longer supported. Leave the information in the Customer/CompanyInfo for now. --- templates/invoice.tex.erb | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/invoice.tex.erb b/templates/invoice.tex.erb index 136d561..7c7b515 100644 --- a/templates/invoice.tex.erb +++ b/templates/invoice.tex.erb @@ -54,7 +54,6 @@ yourref=, %% Payment data. term=30, - accountno=<%= @company.accountno %>, accountname=<%= @company.accountname %>, <% unless @company.accountiban.blank? %> iban=<%= @company.accountiban %>, <% end %><% unless @company.bank_bic.blank? %> bic=<%= @company.bank_bic %>,