diff --git a/app/models/form_configuration.rb b/app/models/form_configuration.rb index eaf563791ab0..017d191bfcd3 100644 --- a/app/models/form_configuration.rb +++ b/app/models/form_configuration.rb @@ -114,6 +114,7 @@ def persist_staged_attribute_groups return unless groups attribute_group_rows.store(groups) + WorkPackage.clear_available_custom_fields_cache remove_instance_variable(:@stored_attribute_groups) if defined?(@stored_attribute_groups) end diff --git a/app/models/work_package.rb b/app/models/work_package.rb index 39a069a9fb8d..72b940ec2746 100644 --- a/app/models/work_package.rb +++ b/app/models/work_package.rb @@ -49,6 +49,7 @@ class WorkPackage < ApplicationRecord include OpenProject::Journal::AttachmentHelper + AVAILABLE_CUSTOM_FIELDS_CACHE_PREFIX = "work_package_custom_fields_" DONE_RATIO_OPTIONS = %w[field status].freeze TOTAL_PERCENT_COMPLETE_MODE_OPTIONS = %w[work_weighted_average simple_average].freeze @@ -505,6 +506,10 @@ def self.available_custom_fields(work_package) end end + def self.clear_available_custom_fields_cache + RequestStore.store.delete_if { |key, _| key.to_s.start_with?(AVAILABLE_CUSTOM_FIELDS_CACHE_PREFIX) } + end + def self.preload_available_custom_fields(work_packages) type_variant_ids = type_variant_ids_by_pair(work_packages) @@ -591,7 +596,7 @@ def self.form_configuration_custom_fields_join(variant_ids) private_class_method :form_configuration_custom_fields_join def self.available_custom_field_key(work_package) - :"work_package_custom_fields_#{work_package.project_id}_#{work_package.type_id}" + :"#{AVAILABLE_CUSTOM_FIELDS_CACHE_PREFIX}#{work_package.project_id}_#{work_package.type_id}" end private_class_method :available_custom_field_key diff --git a/spec/models/work_package/work_package_custom_fields_spec.rb b/spec/models/work_package/work_package_custom_fields_spec.rb index 83be8c80c2a4..18a296a9d08f 100644 --- a/spec/models/work_package/work_package_custom_fields_spec.rb +++ b/spec/models/work_package/work_package_custom_fields_spec.rb @@ -457,5 +457,14 @@ def self.change_custom_field_value(work_package, value, save: true) it "offers a field the applied variant's form configuration shows" do expect(work_package.available_custom_fields).to include(field) end + + it "picks up a field the form configuration gained after an earlier lookup" do + later_field = create(:work_package_custom_field) + work_package.available_custom_fields.to_a + + type.default_variant.custom_field_ids |= [later_field.id] + + expect(described_class.find(work_package.id).available_custom_fields).to include(later_field) + end end end diff --git a/spec/workers/import/jira_create_project_work_packages_job_custom_fields_spec.rb b/spec/workers/import/jira_create_project_work_packages_job_custom_fields_spec.rb index 95849b754afc..a442e1f83cd4 100644 --- a/spec/workers/import/jira_create_project_work_packages_job_custom_fields_spec.rb +++ b/spec/workers/import/jira_create_project_work_packages_job_custom_fields_spec.rb @@ -1049,6 +1049,44 @@ def jira_list_field(id:, name:, schema:, context_groups: nil) end end + describe "a field whose first value appears on a later issue of an already imported type" do + let!(:jira_field) do + create(:jira_field, jira_import:, + origin_id: "customfield_10275", + payload: { + "id" => "customfield_10275", + "name" => "CF Text", + "schema" => { + "type" => "string", + "custom" => "com.atlassian.jira.plugin.system.customfieldtypes:textarea", + "customId" => 10275 + } + }) + end + let!(:jira_issue_without_value) do + create(:jira_issue, jira_import:, + origin_id: "10199", + jira_project:, + payload: issue_payload.deep_dup.tap do |payload| + payload["key"] = "DYX-3" + payload["fields"]["summary"] = "Issue without the text value" + payload["fields"].delete("customfield_10275") + end) + end + let!(:jira_issue) do + create(:jira_issue, jira_import:, + origin_id: "10200", + jira_project:, + payload: issue_payload) + end + + before { import_project } + + it "sets the field's value on the issue that introduced it" do + expect(cf_value("CF Text")).to include("**bold**") + end + end + describe "all custom field types in a single import run", with_ee: [:custom_field_hierarchies] do # Registers all field types at once and verifies the correct number of # OP custom fields are created: