Skip to content

Project specific cost types#23208

Draft
oliverguenther wants to merge 1 commit into
devfrom
feat/project-cost-types
Draft

Project specific cost types#23208
oliverguenther wants to merge 1 commit into
devfrom
feat/project-cost-types

Conversation

@oliverguenther
Copy link
Copy Markdown
Member

@oliverguenther oliverguenther commented May 13, 2026

https://community.openproject.org/work_packages/42037

  • Add a projects association to every cost type, similar to a custom field
  • When editing a cost type
    • a new boolean field "For all projects" is added, which is checked in the migration
      • This ensures current behavior stays the same
    • There is a second tab "Projects"
      • This tab behaves identical to the custom field administration, allowing administrators to add cost types
  • When inside the project settings
    • There is a new menu entry "Time and costs"
    • The "Time entry activities" are moved into that menu, as a tab
    • A new tab "Cost types" is added, showing a selection list for all cost types similar to time entry activities
  • When all cost types are disabled in a project, the option to log and show unit costs is removed
  • The edit form and project select is primerized Primerize cost types #23210
    • We remove the rate editing on the index page, in favor of showing rates as a separate tab

@github-actions
Copy link
Copy Markdown

1 Warning
⚠️ Attention developer & reviewer: attribute :project_id found in a Base- or UpdateContract:

  • modules/costs/app/contracts/cost_types/cost_type_projects/base_contract.rb

Allowing project_id to be written outside of the CreateContract means a resource can be moved between projects.
Without explicit permission checks in both the source and the destination project,
a user can move (and thus "steal") resources into a project they control.

Please make sure the contract:

  1. Includes the UnchangedProject concern
  2. Validates the manage-permission against the source project (using with_unchanged_project_id)
  3. Validates the manage-permission against the destination project when project_id_changed?

Example:

include UnchangedProject

MANAGE_PERMISSION = :manage_something

validate :validate_manage_allowed_in_source_project
validate :validate_manage_allowed_in_destination_project

private

def validate_manage_allowed_in_source_project
  if model.new_record?
    errors.add :base, :error_unauthorized unless user.allowed_in_project?(MANAGE_PERMISSION, model.project)
    return
  end

  with_unchanged_project_id do
    errors.add :base, :error_unauthorized unless user.allowed_in_project?(MANAGE_PERMISSION, model.project)
  end
end

def validate_manage_allowed_in_destination_project
  return if model.new_record?
  return unless model.project_id_changed?

  unless user.allowed_in_project?(MANAGE_PERMISSION, model.project)
    errors.add :base, :error_unauthorized
  end
end

If this contract already handles both checks, feel free to resolve this warning.

Generated by 🚫 Danger

@oliverguenther oliverguenther force-pushed the feat/project-cost-types branch 3 times, most recently from 5f019f9 to cdf3b60 Compare May 15, 2026 06:47
@oliverguenther oliverguenther force-pushed the feat/project-cost-types branch from cdf3b60 to 5ee1dd4 Compare May 15, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant