mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Merge pull request #21168 from opf/feature/68864/nextcloud-pdf-storage
Upload artifact in storage when configured
This commit is contained in:
@@ -58,6 +58,44 @@ module Projects
|
||||
service_call
|
||||
end
|
||||
|
||||
def after_perform(service_call)
|
||||
return service_call if store_attachment_locally?
|
||||
|
||||
if project_storage.nil?
|
||||
service_call.errors.add(:base, I18n.t("projects.wizard.create_artifact_storage_error"))
|
||||
return service_call
|
||||
end
|
||||
|
||||
upload_artifact_to_storage(service_call)
|
||||
end
|
||||
|
||||
def upload_artifact_to_storage(service_call)
|
||||
export = create_pdf_export!
|
||||
|
||||
storage_call = Storages::UploadFileService
|
||||
.call(
|
||||
container: service_call.result,
|
||||
project_storage:,
|
||||
file_path: project.project_creation_wizard_artifact_name,
|
||||
file_data: StringIO.new(export.content),
|
||||
filename: export.title
|
||||
)
|
||||
|
||||
storage_call.on_failure do
|
||||
service_call.merge!(storage_call, without_success: true)
|
||||
end
|
||||
|
||||
service_call
|
||||
end
|
||||
|
||||
def project_storage
|
||||
return @project_storage if defined?(@project_storage)
|
||||
|
||||
@project_storage = project
|
||||
.project_storages
|
||||
.find_by(id: project.project_creation_wizard_artifact_export_storage)
|
||||
end
|
||||
|
||||
def create_artifact_work_package
|
||||
create_params = {
|
||||
project:,
|
||||
@@ -65,10 +103,10 @@ module Projects
|
||||
status_id: project.project_creation_wizard_status_when_submitted_id,
|
||||
subject:,
|
||||
assigned_to_id:,
|
||||
attachments: [pdf_attachment],
|
||||
journal_notes:
|
||||
}
|
||||
|
||||
create_params[:attachments] = [pdf_attachment] if store_attachment_locally?
|
||||
WorkPackages::CreateService.new(user:).call(create_params)
|
||||
end
|
||||
|
||||
@@ -86,6 +124,10 @@ module Projects
|
||||
scope: "settings.project_initiation_request.name.options")
|
||||
end
|
||||
|
||||
def store_attachment_locally?
|
||||
project.project_creation_wizard_artifact_export_type == "attachment"
|
||||
end
|
||||
|
||||
def assigned_to_id
|
||||
project.custom_value_for(assignee_custom_field).value
|
||||
end
|
||||
@@ -101,9 +143,12 @@ module Projects
|
||||
.find_by(id: project.project_creation_wizard_assignee_custom_field_id)
|
||||
end
|
||||
|
||||
def pdf_attachment
|
||||
export = Project::PDFExport::ProjectInitiation.new(project).export!
|
||||
def create_pdf_export!
|
||||
Project::PDFExport::ProjectInitiation.new(project).export!
|
||||
end
|
||||
|
||||
def pdf_attachment
|
||||
export = create_pdf_export!
|
||||
file = OpenProject::Files.create_uploaded_file(
|
||||
name: export.title,
|
||||
content_type: export.mime_type,
|
||||
|
||||
@@ -655,6 +655,7 @@ en:
|
||||
success: "Project attributes saved and artifact work package created successfully."
|
||||
progress_label: "%{current} of %{total}"
|
||||
create_artifact_work_package_error: "Failed to create artifact work package"
|
||||
create_artifact_storage_error: "Failed to store artifact in file storage"
|
||||
lists:
|
||||
create:
|
||||
success: "The modified list has been saved as a new list"
|
||||
|
||||
@@ -47,6 +47,7 @@ RSpec.describe Projects::CreateArtifactWorkPackageService do
|
||||
shared_let(:project) do
|
||||
create(
|
||||
:project,
|
||||
name: "Important Project",
|
||||
types: [type],
|
||||
project_custom_fields: [user_custom_field],
|
||||
# project initiation request settings
|
||||
@@ -103,18 +104,6 @@ RSpec.describe Projects::CreateArtifactWorkPackageService do
|
||||
expect(artifact_work_package.assigned_to).to eq(assignee_user)
|
||||
end
|
||||
|
||||
it "attaches the project initiation request pdf file to the artifact work package" do
|
||||
result = instance.call
|
||||
project = result.result
|
||||
|
||||
artifact_work_package = WorkPackage.find(project.project_creation_wizard_artifact_work_package_id)
|
||||
expect(artifact_work_package.attachments.count).to eq(1)
|
||||
|
||||
attachment = artifact_work_package.attachments.first
|
||||
expect(attachment.file.content_type).to eq("application/pdf")
|
||||
expect(attachment.author).to eq(current_user)
|
||||
end
|
||||
|
||||
it "sets the subject to the artifact name configured in the project initiation request settings" do
|
||||
result = instance.call
|
||||
project = result.result
|
||||
@@ -156,5 +145,79 @@ RSpec.describe Projects::CreateArtifactWorkPackageService do
|
||||
expect(artifact_work_package.last_journal.notes).to include(project.project_creation_wizard_work_package_comment)
|
||||
expect(artifact_work_package.last_journal.notes).to include(/<mention[^>]+>@#{assignee_user.name}<\/mention>/)
|
||||
end
|
||||
|
||||
context "when artifact storage is internal" do
|
||||
it "attaches directly to the work package" do
|
||||
project.update(project_creation_wizard_artifact_export_type: "attachment")
|
||||
result = instance.call
|
||||
project = result.result
|
||||
|
||||
artifact_work_package = WorkPackage.find(project.project_creation_wizard_artifact_work_package_id)
|
||||
expect(artifact_work_package.attachments.count).to eq(1)
|
||||
attachment = artifact_work_package.attachments.first
|
||||
date = Date.current.iso8601
|
||||
expect(attachment.content_type).to eq "application/pdf"
|
||||
expect(attachment.filename).to match /Important_Project_Project_mandate_#{date}_\d+-\d+.pdf/
|
||||
end
|
||||
end
|
||||
|
||||
context "when artifact storage is project storage" do
|
||||
let(:storage) { create(:nextcloud_storage_with_local_connection) }
|
||||
let(:project_storage) { create(:project_storage, project:, storage:, project_folder_id: "/project_folder") }
|
||||
|
||||
let(:service_result) { ServiceResult.success(result: nil) }
|
||||
|
||||
before do
|
||||
project.update(
|
||||
project_creation_wizard_artifact_export_type: "file_link",
|
||||
project_creation_wizard_artifact_export_storage: project_storage.id
|
||||
)
|
||||
|
||||
allow(Storages::UploadFileService)
|
||||
.to receive(:call)
|
||||
.and_return(service_result)
|
||||
end
|
||||
|
||||
it "calls the nextcloud storage service" do
|
||||
result = instance.call
|
||||
project = result.result
|
||||
|
||||
expect(result).to be_success
|
||||
artifact_work_package = WorkPackage.find(project.project_creation_wizard_artifact_work_package_id)
|
||||
expect(artifact_work_package.attachments.count).to eq(0)
|
||||
|
||||
date = Date.current.iso8601
|
||||
expect(Storages::UploadFileService)
|
||||
.to have_received(:call)
|
||||
.with(container: project,
|
||||
project_storage:,
|
||||
file_path: "project_mandate",
|
||||
filename: /Important_Project_Project_mandate_#{date}_\d+-\d+.pdf/,
|
||||
file_data: instance_of(StringIO))
|
||||
end
|
||||
|
||||
context "when service call fails" do
|
||||
let(:service_result) do
|
||||
ServiceResult.failure(result: nil).tap do |result|
|
||||
result.errors.add(:base, "Something happened!")
|
||||
end
|
||||
end
|
||||
|
||||
it "keeps the work package, but shows an error" do
|
||||
result = instance.call
|
||||
project = result.result
|
||||
|
||||
expect(Storages::UploadFileService)
|
||||
.to have_received(:call)
|
||||
|
||||
# The outer service is successful, but an error is added
|
||||
expect(result).to be_success
|
||||
expect(result.errors[:base]).to include "Something happened!"
|
||||
|
||||
artifact_work_package = WorkPackage.find(project.project_creation_wizard_artifact_work_package_id)
|
||||
expect(artifact_work_package.attachments.count).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user