Merge remote-tracking branch 'upstream/dev' into feature/budgets_api

Conflicts:
	lib/open_project/costs/engine.rb
pull/6827/head
Jan Sandbrink 10 years ago
commit 59487ebc55
  1. 16
      app/assets/javascripts/costs/editinplace.js
  2. 4
      app/assets/stylesheets/costs/_summarized_cost_entries.css.sass
  3. 3
      app/assets/stylesheets/costs/costs.css.sass
  4. 23
      app/assets/stylesheets/costs/settings.sass
  5. 96
      app/views/costlog/edit.html.erb
  6. 28
      app/views/hooks/costs/_view_projects_settings_members_table_row.html.erb
  7. 25
      app/views/hooks/costs/_view_work_packages_form_details_bottom.html.erb
  8. 46
      app/views/hourly_rates/edit.html.erb
  9. 2
      lib/open_project/costs/engine.rb
  10. 3
      lib/open_project/costs/hooks/work_package_hook.rb
  11. 51
      lib/open_project/costs/patches/work_packages_helper_patch.rb

@ -46,19 +46,23 @@ function edit(obj, name, obj_value) {
var obj_value = typeof(obj_value) != 'undefined' ? obj_value : obj.innerHTML;
var parsed = getCurrencyValue(obj_value);
var value = parsed[0];
var currency = parsed[1]
var currency = parsed[1];
var span_in = '<span id="'+obj.id+'_editor">'
var text = '<input id="'+obj.id+'_edit" name="'+name+'" size="7" value="'+value+'" class="currency" /> '+currency;
var button = '<input id="'+obj.id+'_cancel" type="image" '+ _cancelButtonAttributes +' /> ';
var span_end = '</span>';
var button = '<span id="'+obj.id+'_cancel" class="form--field-affix -transparent"><input id="'+obj.id+'_cancel" type="image" '+ _cancelButtonAttributes +' /> </span>';
var span = '<span id="'+obj.id+'_editor" class="form--text-field-container">';
span += '<input id="'+obj.id+'_edit" class="form--text-field" name="'+name+'" value="'+value+'" class="currency" type="text" /> ';
span += '</span>';
new Insertion.After(obj, span_in+text+button+span_end);
var affix = '<span class="form--field-affix" id="'+obj.id+'_affix">' + currency + '</span>';
new Insertion.After(obj, button + span + affix);
Event.observe(obj.id+'_cancel', 'click', function(){cleanUp(obj)});
}
function cleanUp(obj){
Element.remove(obj.id+'_editor');
Element.remove(obj.id+'_affix');
Element.remove(obj.id+'_cancel');
Element.show(obj);
}

@ -1,7 +1,7 @@
/*-- copyright
* OpenProject Costs Plugin
*
* Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF)
* Copyright (C) 2009 - 2015 the OpenProject Foundation (OPF)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -11,7 +11,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

@ -1,7 +1,7 @@
/*-- copyright
* OpenProject Costs Plugin
*
* Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF)
* Copyright (C) 2009 - 2015 the OpenProject Foundation (OPF)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -20,3 +20,4 @@
@import costs/costs_legacy
@import costs/summarized_cost_entries
@import costs/settings

@ -0,0 +1,23 @@
/*-- copyright
* OpenProject Costs Plugin
*
* Copyright (C) 2009 - 2015 the OpenProject Foundation (OPF)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
table.list.members
.form--text-field.-tiny
min-width: 60px

@ -34,44 +34,70 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
<%= back_url_hidden_field_tag %>
<div class="box">
<p><%= f.text_field :work_package_id, :size => 6, :required => true %> <em><%= h("#{@cost_entry.work_package.to_s}") if @cost_entry.work_package%></em></p>
<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('cost_entry_spent_on') %></p>
<% if User.current.allowed_to? :log_costs, @project %>
<p><%= f.select :user_id, user_collection_for_select_options, :required => true %></p>
<% else %>
<%= f.hidden_field :user_id, :value => User.current.id %>
<% end %>
<p><%= f.select :cost_type_id, cost_types_collection_for_select_options, :required => true %></p>
<p>
<span class="inline-label">
<%= f.text_field :units, :size => 6, :required => true %>
<span id="cost_entry_unit_name" class="form-label">
<%= (@cost_entry.units == 1 ? @cost_entry.cost_type.unit : @cost_entry.cost_type.unit_plural) if @cost_entry.cost_type %>
</span>
</span>
<%= observe_field( "cost_entry_cost_type_id", :url => {:controller => :cost_objects, :action => :update_material_budget_item, :project_id => @cost_entry.project}, :with => "'cost_type_id=' + encodeURIComponent(value) + '&units=' + encodeURIComponent(document.getElementById('cost_entry_units').value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_entry_spent_on').value) + '&element_id=cost_entry'") %>
<%= observe_field( "cost_entry_units", :frequency => 1, :url => {:controller => :cost_objects, :action => :update_material_budget_item, :project_id => @cost_entry.project}, :with => "'cost_type_id=' + encodeURIComponent(document.getElementById('cost_entry_cost_type_id').value) + '&units=' + encodeURIComponent(value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_entry_spent_on').value) + '&element_id=cost_entry'") %>
<%= observe_field( "cost_entry_spent_on", :frequency => 1, :url => {:controller => :cost_objects, :action => :update_material_budget_item, :project_id => @cost_entry.project}, :with => "'cost_type_id=' + encodeURIComponent(document.getElementById('cost_entry_cost_type_id').value) + '&units=' + encodeURIComponent(document.getElementById('cost_entry_units').value) + '&fixed_date=' + encodeURIComponent(value) + '&element_id=cost_entry'") %>
</p>
<p>
<label for="cost_entry_costs_edit"><%= CostEntry.human_attribute_name(:costs) %></label>
<% if User.current.allowed_to? :view_cost_rates, @cost_entry.project %>
<a href="javascript:;" id="cost_entry_costs" class="icon-context icon-edit" title="<%= l(:help_click_to_edit) %>">
<%= number_to_currency(@cost_entry.calculated_costs) %>
</a>
<%= update_page_tag do |page|
page << "makeEditable('cost_entry_costs', 'cost_entry[overridden_costs]');"
page << "edit($('cost_entry_costs'), 'cost_entry[overridden_costs]', '#{number_to_currency(@cost_entry.overridden_costs)}');" if @cost_entry.overridden_costs
end %>
<div class="form--field">
<%= f.text_field :work_package_id, :size => 6, :required => true %>
<% if @cost_entry.work_package %>
<div class="form--field-instructions">
<%= h("#{@cost_entry.work_package.to_s}") %>
</div>
<% end %>
</div>
<div class="form--field">
<%= f.text_field :spent_on, :size => 10, :required => true %>
<%= calendar_for('cost_entry_spent_on') %>
</div>
<% if User.current.allowed_to? :log_costs, @project %>
<div class="form--field">
<%= f.select :user_id, user_collection_for_select_options, :required => true %>
</div>
<% else %>
<span id="cost_entry_costs_editor">
<input class="currency" value="<%= number_to_currency(@cost_entry.overridden_costs, :unit => "").strip if @cost_entry.overridden_costs %>" size="7" name="cost_entry[overridden_costs]" id="cost_entry_costs_edit"/> <%= Setting.plugin_openproject_costs['costs_currency'] %>
</span>
<br /><em><%= l(:help_override_rate) %></em>
<%= f.hidden_field :user_id, :value => User.current.id %>
<% end %>
<div class="form--field">
<%= f.select :cost_type_id, cost_types_collection_for_select_options, :required => true %></p>
</div>
<div class="form--field">
<%= f.label :units %>
<% suffix = @cost_entry.cost_type.nil? ? '' : (@cost_entry.units == 1 ? @cost_entry.cost_type.unit : @cost_entry.cost_type.unit_plural) %>
<span class="form--field-container">
<%= f.text_field :units, size: 6, required: true, no_label: true %>
<% if @cost_entry.cost_type %>
<span class="form--field-affix" id="cost_entry_unit_name">
<%= h(@cost_entry.units == 1 ? @cost_entry.cost_type.unit : @cost_entry.cost_type.unit_plural) %>
</span>
<% end %>
</span>
<%= observe_field( "cost_entry_cost_type_id", :url => {:controller => :cost_objects, :action => :update_material_budget_item, :project_id => @cost_entry.project}, :with => "'cost_type_id=' + encodeURIComponent(value) + '&units=' + encodeURIComponent(document.getElementById('cost_entry_units').value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_entry_spent_on').value) + '&element_id=cost_entry'") %>
<%= observe_field( "cost_entry_units", :frequency => 1, :url => {:controller => :cost_objects, :action => :update_material_budget_item, :project_id => @cost_entry.project}, :with => "'cost_type_id=' + encodeURIComponent(document.getElementById('cost_entry_cost_type_id').value) + '&units=' + encodeURIComponent(value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_entry_spent_on').value) + '&element_id=cost_entry'") %>
<%= observe_field( "cost_entry_spent_on", :frequency => 1, :url => {:controller => :cost_objects, :action => :update_material_budget_item, :project_id => @cost_entry.project}, :with => "'cost_type_id=' + encodeURIComponent(document.getElementById('cost_entry_cost_type_id').value) + '&units=' + encodeURIComponent(document.getElementById('cost_entry_units').value) + '&fixed_date=' + encodeURIComponent(value) + '&element_id=cost_entry'") %>
</div>
<div class="form--field">
<label for="cost_entry_costs_edit" class="form--label"><%= CostEntry.human_attribute_name(:costs) %></label>
<span class="form--field-container">
<% if User.current.allowed_to? :view_cost_rates, @cost_entry.project %>
<a href="javascript:;" id="cost_entry_costs" class="icon-context icon-edit" title="<%= l(:help_click_to_edit) %>">
<%= number_to_currency(@cost_entry.calculated_costs) %>
</a>
<%= update_page_tag do |page|
page << "makeEditable('cost_entry_costs', 'cost_entry[overridden_costs]');"
page << "edit($('cost_entry_costs'), 'cost_entry[overridden_costs]', '#{number_to_currency(@cost_entry.overridden_costs)}');" if @cost_entry.overridden_costs
end %>
<% else %>
<span id="cost_entry_costs_editor" class="form--text-field-container">
<input class="currency form--text-field" value="<%= number_to_currency(@cost_entry.overridden_costs, :unit => "").strip if @cost_entry.overridden_costs %>" size="7" name="cost_entry[overridden_costs]" id="cost_entry_costs_edit"/> <%= Setting.plugin_openproject_costs['costs_currency'] %>
</span>
<br /><em><%= l(:help_override_rate) %></em>
<% end %>
</span>
</div>
</p>
<p><%= f.text_field :comments, :size => 100 %></p>
<div class="form--field">
<%= f.text_field :comments, size: 100 %>
</div>
</div>
<%= submit_tag l(:button_save), class: 'button -highlight' %>

@ -40,17 +40,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
<% if allow_edit %>
<td align="center" style="white-space: nowrap;">
<%= remote_form_for :rate, :url => { :controller => '/hourly_rates', :action => 'set_rate', :id => member.user, :project_id => project}, :method => :posts do |f| %>
<span class="inline-label">
<label class="hidden-for-sighted", for="rate_text_field_for_<%= member.user.id %>"><%= l(:caption_set_rate) %></label>
<%= f.text_field :rate, :value => "", :name => :rate, :size => 7, :id => "rate_text_field_for_#{member.user.id}" %>
<span class="form-label">
<%= Setting.plugin_openproject_costs['costs_currency'] %>
</span>
<span class="form-label">
<a href="#" onclick="submitFormWithConfirmation(event, this, false);" class="set_current_rate no-decoration-on-hover"><%= icon_wrapper('icon icon-save1', I18n.t(:button_save)) %></a>
</span>
</span>
<%= remote_form_for :rate, :url => { :controller => '/hourly_rates', :action => 'set_rate', :id => member.user, :project_id => project}, :method => :post, html: { class: 'form' } do |f| %>
<div class="form--field">
<label class="hidden-for-sighted form-label", for="rate_text_field_for_<%= member.user.id %>"><%= l(:caption_set_rate) %></label>
<div class="form--field-container">
<div class="form--text-field-container">
<%= f.text_field :rate, :value => "", :name => :rate, :size => 7, :id => "rate_text_field_for_#{member.user.id}", class: 'form--text-field -tiny' %>
</div>
<div class="form--field-affix">
<small>
<%= Setting.plugin_openproject_costs['costs_currency'] %>
</small>
</div>
<div class="form--field-affix">
<a href="#" onclick="submitFormWithConfirmation(event, this, false);" class="set_current_rate no-decoration-on-hover"><%= icon_wrapper('icon icon-save1', I18n.t(:button_save)) %></a>
</div>
</div>
</div>
<% end %>
</td>
<% else %>

@ -1,25 +0,0 @@
<%#-- copyright
OpenProject Costs Plugin
Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 3.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
++#%>
<% if @project && @project.module_enabled?(:costs_module) %>
<div class="form--field">
<%= form.select :cost_object_id, CostObject.find_all_by_project_id(@project, :order => 'subject ASC').collect { |d| [d.subject, d.id] }, :include_blank => true%>
</div>
<% end %>

@ -34,27 +34,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
<% end -%>
<%= labelled_tabular_form_for @user, :url => {:action => 'update', :project_id => @project}, :method => :put do |f| %>
<%= back_url_hidden_field_tag %>
<%= error_messages_for 'user' %>
<%- @rates.each do |rate| -%>
<%- @rate = rate -%>
<%= error_messages_for 'rate' %>
<%- end -%>
<table class="list" style="width:auto">
<thead><tr>
<th><%= Rate.human_attribute_name(:valid_from) %></th>
<th class="currency"><%= Rate.model_name.human %></th>
<th></th>
</tr></thead>
<tbody id="rates_body">
<%- @rates.each_with_index do |rate, index| -%>
<%= render :partial => 'rate', :object => rate, :locals => {:index => index, :classes => cycle('odd', 'even')} %>
<%- end -%>
</tbody>
</table>
<div>
<label class="hidden-for-sighted", for="add_rate_date" %>"><%= l(:description_date_for_new_rate) %></label>
<%= link_to_function l(:button_add_rate), "addRate($('add_rate_date'))", {:class => "button icon icon-add"} %>
</div>
<div><%= submit_tag l(:button_save), class: 'button -highlight' %></div>
<%= back_url_hidden_field_tag %>
<%= error_messages_for 'user' %>
<%- @rates.each do |rate| -%>
<%- @rate = rate -%>
<%= error_messages_for 'rate' %>
<%- end -%>
<table class="list" style="width:auto">
<thead><tr>
<th><%= Rate.human_attribute_name(:valid_from) %></th>
<th class="currency"><%= Rate.model_name.human %></th>
<th></th>
</tr></thead>
<tbody id="rates_body">
<%- @rates.each_with_index do |rate, index| -%>
<%= render :partial => 'rate', :object => rate, :locals => {:index => index, :classes => cycle('odd', 'even')} %>
<%- end -%>
</tbody>
</table>
<div>
<label class="hidden-for-sighted", for="add_rate_date" %>"><%= l(:description_date_for_new_rate) %></label>
<%= link_to_function l(:button_add_rate), "addRate($('add_rate_date'))", {:class => "button icon icon-add"} %>
</div>
<div><%= submit_tag l(:button_save), class: 'button -highlight' %></div>
<% end %>

@ -101,7 +101,7 @@ module OpenProject::Costs
end
patches [:WorkPackage, :Project, :Query, :User, :TimeEntry, :PermittedParams,
:ProjectsController, :ApplicationHelper, :UsersHelper]
:ProjectsController, :ApplicationHelper, :UsersHelper, :WorkPackagesHelper]
patch_with_namespace :API, :V3, :WorkPackages, :Schema, :WorkPackageSchema
allow_attribute_update :work_package, :cost_object_id

@ -22,9 +22,6 @@ class OpenProject::Costs::Hooks::WorkPackageHook < Redmine::Hook::ViewListener
# Renders the Cost Object subject and basic costs information
# render_on :view_work_packages_show_details_bottom, :partial => 'hooks/costs/view_work_packages_show_details_bottom'
# Renders a select tag with all the Cost Objects
render_on :view_work_packages_form_details_bottom, :partial => 'hooks/costs/view_work_packages_form_details_bottom'
# Renders a select tag with all the Cost Objects for the bulk edit page
render_on :view_work_packages_bulk_edit_details_bottom, :partial => 'hooks/costs/view_work_packages_bulk_edit_details_bottom'

@ -0,0 +1,51 @@
#-- copyright
# OpenProject Costs Plugin
#
# Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#++
module OpenProject::Costs::Patches::WorkPackagesHelperPatch
def self.included(base)
base.class_eval do
unloadable
def work_package_form_all_middle_attributes_with_costs(form, work_package, locals = {})
attributes = work_package_form_all_middle_attributes_without_costs(form, work_package, locals)
if work_package.project.module_enabled?(:costs_module)
attributes << work_package_form_budget_attribute(form, work_package, locals)
end
attributes.compact
end
def work_package_form_budget_attribute(form, work_package, locals)
field = work_package_form_field do
options = CostObject.find_all_by_project_id(@project, :order => 'subject ASC').collect { |d| [d.subject, d.id] }
form.select(:cost_object_id, options, include_blank: true)
end
WorkPackagesHelper::WorkPackageAttribute.new(:cost_object_id, field)
end
alias_method_chain :work_package_form_all_middle_attributes, :costs
end
end
end
WorkPackagesHelper.send(:include, OpenProject::Costs::Patches::WorkPackagesHelperPatch)
Loading…
Cancel
Save