diff --git a/modules/budgets/app/components/budgets/child_budgets_row_component.rb b/modules/budgets/app/components/budgets/child_budgets_row_component.rb deleted file mode 100644 index b283249fb09..00000000000 --- a/modules/budgets/app/components/budgets/child_budgets_row_component.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -module Budgets - class ChildBudgetsRowComponent < ::OpPrimer::BorderBoxRowComponent - def budget_relation - model - end - - def budget - budget_relation.child_budget - end - - def id - link_to "##{budget.id}", budget_path(budget) - end - - def subject - link_to budget.subject, budget_path(budget) - end - - def project - link_to budget.project.name, project_path(budget.project) - end - - def relation_type - I18n.t(budget_relation.relation_type, scope: %i[activerecord attributes budget_relation relation_types]) - end - - def budget_amount - number_to_currency(budget.budget) - end - end -end diff --git a/modules/budgets/app/components/budgets/child_budgets_table_component.rb b/modules/budgets/app/components/budgets/child_budgets_table_component.rb deleted file mode 100644 index cffbb38a800..00000000000 --- a/modules/budgets/app/components/budgets/child_budgets_table_component.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -module Budgets - class ChildBudgetsTableComponent < ::OpPrimer::BorderBoxTableComponent - columns :id, :subject, :project, :relation_type, :budget_amount - main_column :subject, :proejct, :relation_type, :budget_amount - - def sortable? - false - end - - def paginated? - false - end - - def has_actions? - false - end - - def empty_row_message - I18n.t :no_results_title_text - end - - def row_class - Budgets::ChildBudgetsRowComponent - end - - def mobile_title - I18n.t(:label_budget_child_budgets) - end - - def headers - [ - [:id, { caption: Budget.human_attribute_name(:id) }], - [:subject, { caption: Budget.human_attribute_name(:subject) }], - [:project, { caption: Budget.human_attribute_name(:project) }], - [:relation_type, { caption: BudgetRelation.human_attribute_name(:relation_type) }], - [:budget_amount, { caption: Budget.human_attribute_name(:budget) }] - ] - end - end -end diff --git a/modules/budgets/app/components/budgets/parent_page_header_component.rb b/modules/budgets/app/components/budgets/parent_page_header_component.rb deleted file mode 100644 index 8525edb658d..00000000000 --- a/modules/budgets/app/components/budgets/parent_page_header_component.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -# -- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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. -# -# See COPYRIGHT and LICENSE files for more details. -# ++ - -module Budgets - class ParentPageHeaderComponent < ApplicationComponent - include OpPrimer::ComponentHelpers - include ApplicationHelper - - def initialize(budget:, project:) - super - - @budget = budget - @project = project - end - - def breadcrumb_items - [ - { href: project_overview_path(@project.id), text: @project.name }, - { href: projects_budgets_path(@project.id), text: t(:label_budget_plural) }, - { href: budget_path(@budget.id), text: t(:label_budget_id, id: @budget.id) }, - t(:button_manage_parent) - ] - end - - def call - render(Primer::OpenProject::PageHeader.new) do |header| - header.with_title { t(:button_manage_parent) } - header.with_breadcrumbs(breadcrumb_items) - end - end - end -end diff --git a/modules/budgets/app/components/budgets/show_page_header_component.html.erb b/modules/budgets/app/components/budgets/show_page_header_component.html.erb index 52bba5f1a95..14de313d793 100644 --- a/modules/budgets/app/components/budgets/show_page_header_component.html.erb +++ b/modules/budgets/app/components/budgets/show_page_header_component.html.erb @@ -18,21 +18,6 @@ t(:button_update) end end - if authorize_for(:budgets, :parent) && @budget.project.parent_id.present? - header.with_action_button( - tag: :a, - mobile_icon: "git-pull-request", - mobile_label: t(:button_manage_parent), - size: :medium, - href: url_for({ controller: "budgets", action: "parent", id: @budget }), - aria: { label: t(:button_manage_parent) }, - data: { test_selector: "budget-parent-button" }, - title: t(:button_manage_parent) - ) do |button| - button.with_leading_visual_icon(icon: "git-pull-request") - t(:button_manage_parent) - end - end if authorize_for(:budgets, :copy) header.with_action_button( tag: :a, diff --git a/modules/budgets/app/contracts/budgets/base_contract.rb b/modules/budgets/app/contracts/budgets/base_contract.rb index cfebe9302c7..d9f4fb254aa 100644 --- a/modules/budgets/app/contracts/budgets/base_contract.rb +++ b/modules/budgets/app/contracts/budgets/base_contract.rb @@ -38,7 +38,6 @@ module Budgets attribute :description attribute :fixed_date attribute :project - attribute :state attribute :base_amount attribute :new_material_budget_item_attributes, readable: false diff --git a/modules/budgets/app/controllers/budgets_controller.rb b/modules/budgets/app/controllers/budgets_controller.rb index 15f971b6188..2e729949eae 100644 --- a/modules/budgets/app/controllers/budgets_controller.rb +++ b/modules/budgets/app/controllers/budgets_controller.rb @@ -29,7 +29,7 @@ class BudgetsController < ApplicationController include AttachableServiceCall - before_action :find_budget, only: %i[show edit update copy destroy_info parent update_parent destroy_parent] + before_action :find_budget, only: %i[show edit update copy destroy_info] before_action :find_budgets, only: :destroy before_action :check_and_update_belonging_work_packages, only: :destroy before_action :find_project_by_project_id, only: %i[new create update_material_budget_item update_labor_budget_item] @@ -47,12 +47,16 @@ class BudgetsController < ApplicationController helper :sort include SortHelper + helper :projects include ProjectsHelper + helper :attachments include AttachmentsHelper + helper :costlog include CostlogHelper + helper :budgets include BudgetsHelper include PaginationHelper @@ -74,7 +78,6 @@ class BudgetsController < ApplicationController def show @edit_allowed = User.current.allowed_in_project?(:edit_budgets, @project) - @child_budget_relations = @budget.child_budget_relations.includes(child_budget: :project) respond_to do |format| format.html { render action: "show", layout: !request.xhr? } @@ -195,35 +198,6 @@ class BudgetsController < ApplicationController end end - def parent - @parent_projects = @project.ancestors - @budget_candidates = Budget.visible(User.current).where(project_id: @parent_projects) - - @parent_budget_relation = @budget.parent_budget_relation || BudgetRelation.new - end - - def update_parent - parent_relation = @budget.parent_budget_relation || @budget.build_parent_budget_relation - - if parent_relation.update(budget_relation_params) - flash[:notice] = t(:notice_successful_update) - redirect_to budget_path(@budget) - else - flash[:error] = t(:notice_failed_update) - render action: :parent, status: :unprocessable_entity - end - end - - def destroy_parent - if @budget.parent_budget_relation.destroy - flash[:notice] = t(:notice_relation_destroyed) - redirect_to budget_path(@budget), method: :get - else - flash[:error] = t(:notice_failed_delete) - render action: :parent, status: :unprocessable_entity - end - end - private def find_budget @@ -265,10 +239,6 @@ class BudgetsController < ApplicationController response end - def budget_relation_params - params.expect(budget_relation: %i[parent_budget_id relation_type]) - end - def default_budget_sort { "id" => "#{Budget.table_name}.id", diff --git a/modules/budgets/app/models/budget.rb b/modules/budgets/app/models/budget.rb index cbeb41d5561..2ccfd2e834f 100644 --- a/modules/budgets/app/models/budget.rb +++ b/modules/budgets/app/models/budget.rb @@ -46,18 +46,6 @@ class Budget < ApplicationRecord has_many :cost_entries, through: :work_packages has_many :time_entries, through: :work_packages - has_one :parent_budget_relation, class_name: "BudgetRelation", - foreign_key: "child_budget_id", - dependent: :destroy, - inverse_of: :child_budget - - has_one :parent_budget, through: :parent_budget_relation, source: :parent_budget - - has_many :child_budget_relations, class_name: "BudgetRelation", - foreign_key: "parent_budget_id", - dependent: :destroy, - inverse_of: :parent_budget - include ActiveModel::ForbiddenAttributesProtection acts_as_attachable @@ -68,16 +56,7 @@ class Budget < ApplicationRecord url: Proc.new { |o| { controller: "budgets", action: "show", id: o.id } } validates :subject, :project, :author, :fixed_date, presence: true - validates :subject, length: { maximum: 255 } - validates :subject, length: { minimum: 1 } - - enum :state, { - planned: "planned", - draft: "draft", - submitted: "submitted", - approved: "approved", - rejected: "rejected" - }, validate: { allow_nil: true } + validates :subject, length: { minimum: 1, maximum: 255 } class << self def visible(user) @@ -99,8 +78,10 @@ class Budget < ApplicationRecord protected def copy_attributes(source) - source.attributes.slice("project_id", "subject", "description", "fixed_date", "state", - "base_amount").merge("author" => User.current) + source + .attributes + .slice("project_id", "subject", "description", "fixed_date", "base_amount") + .merge("author" => User.current) end def copy_budget_items(source, sink, items:) @@ -119,34 +100,7 @@ class Budget < ApplicationRecord end def budget - base_amount + material_budget + labor_budget + budget_added_by_children - end - - def budget_added_by_children - # TODO: Efficient with query - @budget_added_by_children ||= child_budget_relations.add.includes(:child_budget).sum do |rel| - rel.child_budget.budget - end - end - - def allocated_to_children - # TODO: Efficient with query - @allocated_to_children ||= child_budget_relations.includes(:child_budget).sum { |rel| rel.child_budget.budget } - end - - def allocated_unused - allocated_to_children - spent_on_children - end - - def spent_with_children - spent + spent_on_children - end - - def spent_on_children - # TODO: Efficient with query - @spent_on_children ||= child_budget_relations.includes(:child_budget).sum do |rel| - rel.child_budget.spent_with_children - end + base_amount + material_budget + labor_budget end def type_label @@ -161,9 +115,7 @@ class Budget < ApplicationRecord def budget_ratio return 0.0 if budget.nil? || budget == 0.0 - gone = spent + allocated_to_children - - ((gone / budget) * 100).round + ((spent / budget) * 100).round end def css_classes @@ -215,7 +167,7 @@ class Budget < ApplicationRecord end def available - budget - spent - allocated_to_children + budget - spent end def new_material_budget_item_attributes=(material_budget_item_attributes) diff --git a/modules/budgets/app/models/budget_relation.rb b/modules/budgets/app/models/budget_relation.rb deleted file mode 100644 index c55c142e672..00000000000 --- a/modules/budgets/app/models/budget_relation.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -class BudgetRelation < ApplicationRecord - belongs_to :parent_budget, class_name: "Budget" - belongs_to :child_budget, class_name: "Budget" - - enum :relation_type, { add: "add", subtract: "subtract" }, default: :subtract - - validates :child_budget, uniqueness: true - validates :child_budget, :parent_budget, :relation_type, presence: true -end diff --git a/modules/budgets/app/models/queries/projects/selects/budget_allocated.rb b/modules/budgets/app/models/queries/projects/selects/budget_allocated.rb deleted file mode 100644 index 2f5998741ee..00000000000 --- a/modules/budgets/app/models/queries/projects/selects/budget_allocated.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -# -- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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. -# -# See COPYRIGHT and LICENSE files for more details. -# ++ - -class Queries::Projects::Selects::BudgetAllocated < Queries::Selects::Base - def self.key - :budget_allocated - end - - def caption - I18n.t(:label_budget_allocated) - end -end diff --git a/modules/budgets/app/views/budgets/_form.html.erb b/modules/budgets/app/views/budgets/_form.html.erb index 679a0d3789e..4a047edc603 100644 --- a/modules/budgets/app/views/budgets/_form.html.erb +++ b/modules/budgets/app/views/budgets/_form.html.erb @@ -50,12 +50,6 @@ See COPYRIGHT and LICENSE files for more details. value: unitless_currency_number(@budget.base_amount) %> -