diff --git a/app/controllers/api/messages_controller.rb b/app/controllers/api/messages_controller.rb
index dcecd946f..8fd89a1db 100644
--- a/app/controllers/api/messages_controller.rb
+++ b/app/controllers/api/messages_controller.rb
@@ -24,7 +24,7 @@ def message_drafts
@message.save
permitted_message_draft_params.fetch(:objects, []).each do |object_params|
- message_object = @message.objects.create(object_params.except(:content, :tags))
+ message_object = @message.objects.create(object_params.except(:content, :to_be_signed, :tags))
object_params.fetch(:tags, []).each do |tag_name|
tag = @tenant.user_signature_tags.find_by(name: tag_name)
@@ -33,6 +33,11 @@ def message_drafts
end
@message.thread.box.tenant.signed_externally_tag!.assign_to_message_object(message_object) if message_object.is_signed
+ if object_params[:to_be_signed]
+ @message.tenant.signer_group.signature_requested_from_tag&.assign_to_message_object(message_object)
+ @message.tenant.signer_group.signature_requested_from_tag&.assign_to_thread(@message.thread)
+ end
+
MessageObjectDatum.create(
message_object: message_object,
blob: Base64.decode64(object_params[:content])
diff --git a/app/controllers/message_drafts_controller.rb b/app/controllers/message_drafts_controller.rb
index 9a54a3f1c..ecbaa9c28 100644
--- a/app/controllers/message_drafts_controller.rb
+++ b/app/controllers/message_drafts_controller.rb
@@ -13,7 +13,6 @@ def submit
if @message.submit
redirect_to message_thread_path(@message.thread), notice: "Správa bola zaradená na odoslanie"
else
- # TODO FIX: Tato hlaska sa zobrazuje aj ked je object oznaceny ako to_be_signed, ale nebol este podpisany
redirect_to message_thread_path(@message.thread), alert: @message.not_submittable_errors.join(', ')
end
end
diff --git a/app/controllers/message_threads/bulk/message_drafts_controller.rb b/app/controllers/message_threads/bulk/message_drafts_controller.rb
index 05fecbad6..9a1a54030 100644
--- a/app/controllers/message_threads/bulk/message_drafts_controller.rb
+++ b/app/controllers/message_threads/bulk/message_drafts_controller.rb
@@ -9,10 +9,12 @@ def submit
message_threads = message_thread_policy_scope.where(id: ids).includes(:messages)
message_threads.transaction do
submission_results = SubmitMessageDraftsAction.run(message_threads)
- if submission_results
- redirect_back fallback_location: message_threads_path, notice: "Správy vo vláknach boli zaradené na odoslanie", status: 303
- else
+ if submission_results.none?(true)
+ redirect_back fallback_location: message_threads_path, alert: "Vo vláknach sa našli správy, ktoré neboli podpísané všetkými podpismi", status: 303 and return if any_missing_signature?(message_threads)
redirect_back fallback_location: message_threads_path, alert: "Vo vláknach sa nenašli žiadne správy na odoslanie", status: 303
+ else
+ redirect_back fallback_location: message_threads_path, alert: "Správy, ktoré neboli podpísané všetkými podpismi neboli zaradené na odoslanie", status: 303 and return if any_missing_signature?(message_threads)
+ redirect_back fallback_location: message_threads_path, notice: "Správy vo vláknach boli zaradené na odoslanie", status: 303
end
end
end
@@ -41,6 +43,10 @@ def destroy
def message_thread_policy_scope
policy_scope(MessageThread)
end
+
+ def any_missing_signature?(message_threads)
+ MessageThreadsTag.where(message_thread: message_threads, tag: Current.tenant.tags.signature_requesting).exists?
+ end
end
end
end
diff --git a/app/jobs/upvs/drafts/load_content_job.rb b/app/jobs/upvs/drafts/load_content_job.rb
index 9180ffa49..e3a041f65 100644
--- a/app/jobs/upvs/drafts/load_content_job.rb
+++ b/app/jobs/upvs/drafts/load_content_job.rb
@@ -39,12 +39,16 @@ def load_message_draft_objects(message_draft, objects_path, signed:, to_be_signe
mimetype: Utils.file_mimetype_by_name(entry_name: file_name, is_form: is_form),
object_type: is_form ? "FORM" : "ATTACHMENT",
is_signed: signed,
- to_be_signed: to_be_signed,
message: message_draft,
visualizable: is_form ? false : nil,
tags: tags
)
+ if to_be_signed
+ message_draft_object.message.tenant.signer_group.signature_requested_from_tag&.assign_to_message_object(message_draft_object)
+ message_draft_object.message.tenant.signer_group.signature_requested_from_tag&.assign_to_thread(message_draft_object.message.thread)
+ end
+
MessageObjectDatum.create(
message_object: message_draft_object,
blob: File.read(File.join(objects_path, file_name))
diff --git a/app/models/fs/message_draft.rb b/app/models/fs/message_draft.rb
index 18b9d9abf..c23776006 100644
--- a/app/models/fs/message_draft.rb
+++ b/app/models/fs/message_draft.rb
@@ -70,13 +70,12 @@ def self.create_and_validate_with_fs_form(form_files: [], author:, fs_client: Fs
form_object = message.objects.create(
object_type: 'FORM',
name: form_file.original_filename,
- mimetype: form_file.content_type,
- to_be_signed: fs_form.signature_required
+ mimetype: form_file.content_type
)
form_object.update(is_signed: form_object.asice?)
message.thread.box.tenant.signed_externally_tag!.assign_to_message_object(form_object) if form_object.is_signed?
- if form_object.to_be_signed && !form_object.is_signed?
+ if fs_form.signature_required && !form_object.is_signed?
message.thread.box.tenant.signer_group.signature_requested_from_tag&.assign_to_message_object(form_object)
message.thread.box.tenant.signer_group.signature_requested_from_tag&.assign_to_thread(message.thread)
end
diff --git a/app/models/message.rb b/app/models/message.rb
index c86f7512c..edd77d2ce 100644
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -96,6 +96,10 @@ def authorized?
metadata["delivery_notification"] && metadata["authorized"] == true
end
+ def any_objects_with_requested_signature?
+ MessageObjectsTag.where(message_object: objects, tag: tenant.tags.signature_requesting).exists?
+ end
+
# TODO remove UPVS stuff from core domain
def form
::Upvs::Form.find_by(
diff --git a/app/models/message_draft.rb b/app/models/message_draft.rb
index 2e03797a8..3a651ccd2 100644
--- a/app/models/message_draft.rb
+++ b/app/models/message_draft.rb
@@ -106,7 +106,7 @@ def created_from_template?
end
def submittable?
- form_object.content.present? && objects.to_be_signed.all? { |o| o.is_signed? } && correctly_created? && valid?(:validate_data)
+ form_object&.content&.present? && correctly_created? && valid?(:validate_data) && !any_objects_with_requested_signature?
end
def not_submittable_errors
@@ -114,7 +114,7 @@ def not_submittable_errors
errors = []
errors << 'Vyplňte obsah správy' unless form_object.content.present?
- errors << 'Pred odoslaním podpíšte všetky dokumenty na podpis' unless objects.to_be_signed.all? { |o| o.is_signed? }
+ errors << 'Pred odoslaním podpíšte všetky dokumenty na podpis' if any_objects_with_requested_signature?
errors << 'Obsah správy nie je validný' if invalid? || !valid?(:validate_data)
errors << 'Správu bude možné odoslať až po ukončení validácie' if being_validated?
diff --git a/app/models/message_object.rb b/app/models/message_object.rb
index 33e763609..30215df7a 100644
--- a/app/models/message_object.rb
+++ b/app/models/message_object.rb
@@ -7,7 +7,6 @@
# mimetype :string
# name :string
# object_type :string not null
-# to_be_signed :boolean default(FALSE), not null
# uuid :uuid
# visualizable :boolean
# created_at :datetime not null
@@ -25,8 +24,6 @@ class MessageObject < ApplicationRecord
has_one :archived_object, dependent: :destroy
scope :unsigned, -> { where(is_signed: false) }
- scope :to_be_signed, -> { where(to_be_signed: true) }
- scope :should_be_signed, -> { where(to_be_signed: true, is_signed: false) }
validates :name, presence: { message: "Name can't be blank" }, on: :validate_data
validate :allowed_mimetype?, on: :validate_data
@@ -163,11 +160,11 @@ def thread
def remove_object_related_tags_from_thread
tags.each do |tag|
- message.thread.unassign_tag(tag) unless other_thread_objects_include_tag?(tag)
+ thread.unassign_tag(tag) unless other_thread_objects_include_tag?(tag)
end
- message.thread.unassign_tag(message.tenant.signed_tag!) unless message.thread.tags.reload.where(type: SignedByTag.to_s).any?
- message.thread.unassign_tag(message.tenant.signature_requested_tag!) unless message.thread.tags.reload.where(type: SignatureRequestedFromTag.to_s).any?
+ thread.unassign_tag(message.tenant.signed_tag!) unless thread.tags.reload.where(type: SignedByTag.to_s).any?
+ thread.unassign_tag(message.tenant.signature_requested_tag!) unless thread.tags.reload.where(type: SignatureRequestedFromTag.to_s).any?
end
def other_thread_objects_include_tag?(tag)
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 9df1e434f..3fcad2b2d 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -39,6 +39,7 @@ class Tag < ApplicationRecord
scope :signing_tags, -> { where(type: ["SignedTag", "SignedByTag", "SignatureRequestedTag", "SignatureRequestedFromTag"]) }
scope :signed, -> { where(type: ["SignedTag", "SignedByTag", "SignedExternallyTag"]) }
scope :signed_by, -> { where(type: "SignedByTag") }
+ scope :signature_requesting, -> { where(type: "SignatureRequestedFromTag") }
scope :signed_internally, -> { where(type: ["SignedTag", "SignedByTag"]) }
scope :archived, -> { where(type: ArchivedTag.to_s) }
diff --git a/db/migrate/20241029064753_remove_to_be_signed_attribute_from_message_objects.rb b/db/migrate/20241029064753_remove_to_be_signed_attribute_from_message_objects.rb
new file mode 100644
index 000000000..50256c12c
--- /dev/null
+++ b/db/migrate/20241029064753_remove_to_be_signed_attribute_from_message_objects.rb
@@ -0,0 +1,5 @@
+class RemoveToBeSignedAttributeFromMessageObjects < ActiveRecord::Migration[7.1]
+ def change
+ remove_column :message_objects, :to_be_signed
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a42c507fa..1b82c0a91 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.1].define(version: 2024_10_25_151903) do
+ActiveRecord::Schema[7.1].define(version: 2024_10_29_064753) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@@ -387,7 +387,6 @@
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "is_signed"
- t.boolean "to_be_signed", default: false, null: false
t.boolean "visualizable"
t.uuid "uuid"
t.index ["message_id"], name: "index_message_objects_on_message_id"
diff --git a/public/openapi.yaml b/public/openapi.yaml
index 85eff9eba..da517fe51 100644
--- a/public/openapi.yaml
+++ b/public/openapi.yaml
@@ -351,7 +351,7 @@ paths:
description: Indikátor či je obsah objektu podpísaný
type: boolean
to_be_signed:
- description: Indikátor či obsah objektu má byť podpísaný
+ description: Indikátor či obsah objektu má byť podpísaný. V prípade hodnoty true je vyžiadaný podpis na danom objekte
type: boolean
mimetype:
description: Typ internetového média v súlade s typom a obsahom objektu
diff --git a/test/fixtures/message_object_data.yml b/test/fixtures/message_object_data.yml
index b01660fca..b392fe4a5 100644
--- a/test/fixtures/message_object_data.yml
+++ b/test/fixtures/message_object_data.yml
@@ -8,10 +8,18 @@ two:
message_object: ssd_main_general_two_form
blob: MyText
+main_draft:
+ message_object: ssd_main_draft_form
+ blob: predmettext
+
draft_two:
message_object: ssd_main_general_draft_two_form
blob: predmettext
+draft_three:
+ message_object: ssd_main_draft_to_be_signed2_draft_form
+ blob: predmettext
+
empty_draft:
message_object: ssd_main_empty_draft_form
blob:
diff --git a/test/fixtures/message_objects.yml b/test/fixtures/message_objects.yml
index c6e355c1f..7a9739dd4 100644
--- a/test/fixtures/message_objects.yml
+++ b/test/fixtures/message_objects.yml
@@ -49,6 +49,12 @@ ssd_main_fs_one_form:
mimetype: application/x-eform-xml
object_type: FORM
+ssd_main_draft_form:
+ message: ssd_main_draft
+ name: MyString
+ mimetype: application/x-eform-xml
+ object_type: FORM
+
ssd_main_draft_to_be_signed_draft_one_form:
uuid: 6a0f716a-c284-4680-ad7e-ed2bde769dd2
message: ssd_main_draft_to_be_signed_draft_one
@@ -80,7 +86,7 @@ ssd_main_draft_to_be_signed_draft_two_form:
ssd_main_draft_to_be_signed2_draft_form:
message: ssd_main_draft_to_be_signed2_draft
name: MyString
- mimetype: MyString
+ mimetype: application/x-eform-xml
object_type: FORM
ssd_main_draft_to_be_signed3_draft_one_form:
diff --git a/test/fixtures/messages.yml b/test/fixtures/messages.yml
index e189d0928..e83e75a97 100644
--- a/test/fixtures/messages.yml
+++ b/test/fixtures/messages.yml
@@ -217,7 +217,7 @@ ssd_main_draft_to_be_signed_draft_two:
author: basic
ssd_main_draft_to_be_signed2_draft:
- type: MessageDraft
+ type: Upvs::MessageDraft
uuid: <%= SecureRandom.uuid %>
title: MyStringDraft3
html_visualization: MyString
@@ -226,6 +226,13 @@ ssd_main_draft_to_be_signed2_draft:
replyable: false
metadata:
status: created
+ sktalk_class: EGOV_APPLICATION
+ posp_id: App.GeneralAgenda
+ posp_version: 1.9
+ message_type: App.GeneralAgenda
+ correlation_id: <%= SecureRandom.uuid %>
+ recipient_uri:
+ ico://sk/12345678
author: basic
ssd_main_draft_to_be_signed3_draft:
diff --git a/test/integration/upvs_message_drafts_api_test.rb b/test/integration/upvs_message_drafts_api_test.rb
index 670dd2eb4..94c1b20c5 100644
--- a/test/integration/upvs_message_drafts_api_test.rb
+++ b/test/integration/upvs_message_drafts_api_test.rb
@@ -43,6 +43,42 @@ class UpvsMessageDraftsApiTest < ActionDispatch::IntegrationTest
assert_not_equal Message.count, @before_request_messages_count
end
+ test 'SignatureRestedTag is assigned from SignerGroup if object marked to_be_signed' do
+ message_params = {
+ type: 'Upvs::MessageDraft',
+ title: 'Všeobecná agenda',
+ uuid: SecureRandom.uuid,
+ metadata: {
+ posp_id: 'App.GeneralAgenda',
+ posp_version: '1.9',
+ message_type: 'App.GeneralAgenda',
+ correlation_id: SecureRandom.uuid,
+ sender_uri: 'SSDMainURI',
+ recipient_uri: 'ico://sk/12345678',
+ },
+ objects: [
+ {
+ name: 'Form.xml',
+ is_signed: false,
+ to_be_signed: true,
+ mimetype: 'application/x-eform-xml',
+ object_type: 'FORM',
+ content: Base64.encode64('
+
+ Všeobecný predmet
+ Všeobecný text
+')
+ }
+ ]
+ }
+
+ post '/api/messages/message_drafts', params: message_params.merge({ token: generate_api_token(sub: @tenant.id, key_pair: @key_pair)} ), as: :json
+
+ assert_response :created
+ assert @box.messages.last.objects.first.tags.include?(@tenant.signer_group.signature_requested_from_tag)
+ assert @box.messages.last.thread.tags.include?(@tenant.signature_requested_tag!)
+ end
+
test 'can upload valid message with tags if they exist' do
message_params = {
type: 'Upvs::MessageDraft',
diff --git a/test/models/message_object_test.rb b/test/models/message_object_test.rb
index 7d0f4c043..f3e109145 100644
--- a/test/models/message_object_test.rb
+++ b/test/models/message_object_test.rb
@@ -206,6 +206,15 @@ class MessageObjectTest < ActiveSupport::TestCase
assert_not object.message.thread.tags.include?(tenant.signed_tag!)
end
+ test "before_destroy callback deletes SignatureRequested Tag from message thread (if no more objects with SignatureRequestedFromTag present)" do
+ message_object = message_objects(:ssd_main_draft_form)
+ message_thread = message_object.message.thread
+
+ message_object.destroy
+
+ assert_equal false, message_thread.tags.reload.include?(message_thread.tenant.signature_requested_tag!)
+ end
+
test "before_destroy callback keeps object related tags for message thread (if another objects with the tag present in the message)" do
tenant = tenants(:ssd)
signer = users(:basic_two)
diff --git a/test/system/message_drafts_test.rb b/test/system/message_drafts_test.rb
index c29b01a07..24e8e6cbf 100644
--- a/test/system/message_drafts_test.rb
+++ b/test/system/message_drafts_test.rb
@@ -56,4 +56,19 @@ class MessageDraftsTest < ApplicationSystemTestCase
refute_selector(thread_in_listing_selector(thread_general))
refute_selector(thread_in_listing_selector(thread_issue))
end
+
+ test "message is not submitted and flash message is shown when user tries to send message without requested signatures present" do
+ message_thread = message_threads(:ssd_main_draft_to_be_signed2)
+ message_draft = messages(:ssd_main_draft_to_be_signed2_draft)
+
+ visit message_thread_path(message_thread)
+
+ within("#upvs_message_draft_#{message_draft.id}") do
+ assert_button "Odoslať"
+
+ click_button "Odoslať"
+ end
+
+ assert_text "Pred odoslaním podpíšte všetky dokumenty na podpis"
+ end
end