Files
docuseal/lib/submitters/create_stamp_attachment.rb
T

111 lines
3.6 KiB
Ruby
Raw Normal View History

2023-12-22 13:33:53 +02:00
# frozen_string_literal: true
module Submitters
module CreateStampAttachment
WIDTH = 400
HEIGHT = 200
2026-04-01 11:10:09 +03:00
LRM = "\u200E"
2023-12-22 13:33:53 +02:00
module_function
2024-03-14 14:09:43 +02:00
def call(submitter, with_logo: true)
2024-06-13 22:57:29 +03:00
attachment = build_attachment(submitter, with_logo:)
attachment.save!
attachment
end
def build_attachment(submitter, with_logo: true)
2024-03-14 14:09:43 +02:00
image = generate_stamp_image(submitter, with_logo:)
2023-12-22 13:33:53 +02:00
2026-05-23 09:30:56 +03:00
image_data = image.write_to_buffer('.png', strip: true)
2023-12-22 13:33:53 +02:00
checksum = Digest::MD5.base64digest(image_data)
attachment = submitter.attachments.joins(:blob).find_by(blob: { checksum: })
2024-06-13 22:57:29 +03:00
attachment || submitter.attachments_attachments.new(
2023-12-22 13:33:53 +02:00
blob: ActiveStorage::Blob.create_and_upload!(io: StringIO.new(image_data), filename: 'stamp.png'),
2024-06-13 22:57:29 +03:00
metadata: { analyzed: true, identified: true, width: image.width, height: image.height }
2023-12-22 13:33:53 +02:00
)
end
2024-03-14 14:09:43 +02:00
def generate_stamp_image(submitter, with_logo: true)
logo =
if with_logo
2026-05-21 15:38:16 +03:00
ImageUtils.load_vips(load_logo(submitter).read)
2024-03-14 14:09:43 +02:00
else
2026-05-26 11:48:52 +03:00
Vips::Image.black(WIDTH, WIDTH, bands: 4).copy(interpretation: :srgb)
2024-03-14 14:09:43 +02:00
end
2023-12-22 13:33:53 +02:00
logo = logo.resize([WIDTH / logo.width.to_f, HEIGHT / logo.height.to_f].min)
2026-05-30 11:50:36 +03:00
logo = logo.copy(interpretation: :srgb) if logo.interpretation == :multiband
2023-12-22 13:33:53 +02:00
2026-05-26 11:48:52 +03:00
base_layer = Vips::Image.black(WIDTH, HEIGHT).new_from_image([255, 255, 255, 255]).copy(interpretation: :srgb)
2023-12-22 13:33:53 +02:00
2026-05-26 11:48:52 +03:00
opacity_layer = Vips::Image.black(WIDTH, HEIGHT).new_from_image([255, 255, 255, 127]).copy(interpretation: :srgb)
2023-12-22 13:33:53 +02:00
text = build_text_image(submitter)
text_layer = text.new_from_image([0, 0, 0]).copy(interpretation: :srgb)
text_layer = text_layer.bandjoin(text)
base_layer = base_layer.composite(logo, 'over',
x: (WIDTH - logo.width) / 2,
y: (HEIGHT - logo.height) / 2)
base_layer = base_layer.composite(opacity_layer, 'over')
base_layer.composite(text_layer, 'over',
x: (WIDTH - text_layer.width) / 2,
y: (HEIGHT - text_layer.height) / 2)
end
def build_text_image(submitter)
2025-08-19 12:40:45 +03:00
if submitter.completed_at
time = I18n.l(submitter.completed_at.in_time_zone(submitter.submission.account.timezone),
format: :long,
locale: submitter.submission.account.locale)
2023-12-22 13:33:53 +02:00
2025-08-19 12:40:45 +03:00
timezone = TimeUtils.timezone_abbr(submitter.submission.account.timezone, submitter.completed_at)
end
2023-12-22 13:33:53 +02:00
2025-08-19 12:40:45 +03:00
name = build_name(submitter)
role = build_role(submitter)
2023-12-22 13:33:53 +02:00
2024-06-13 22:57:29 +03:00
digitally_signed_by = I18n.t(:digitally_signed_by, locale: submitter.submission.account.locale)
2023-12-28 17:24:25 +02:00
2024-07-02 19:11:42 +03:00
name = ERB::Util.html_escape(name)
role = ERB::Util.html_escape(role)
2026-04-01 11:10:09 +03:00
text =
%(<span size="90">#{LRM}#{digitally_signed_by}:\n#{LRM}<b>#{name}</b>\n#{LRM}#{role}#{time} #{timezone}</span>)
2023-12-22 13:33:53 +02:00
2024-06-04 19:31:55 +03:00
Vips::Image.text(text, width: WIDTH, height: HEIGHT, wrap: :'word-char')
2023-12-22 13:33:53 +02:00
end
2025-08-19 12:40:45 +03:00
def build_name(submitter)
if submitter.name.present? && submitter.email.present?
"#{submitter.name} #{submitter.email}"
else
submitter.name || submitter.email || submitter.phone
end
end
def build_role(submitter)
if submitter.submission.template_submitters.size > 1
item = submitter.submission.template_submitters.find { |e| e['uuid'] == submitter.uuid }
"#{I18n.t(:role, locale: submitter.account.locale)}: #{item['name']}\n"
else
''
end
end
2023-12-22 13:33:53 +02:00
def load_logo(_submitter)
2025-02-06 19:38:27 +02:00
PdfIcons.stamp_logo_io
2023-12-22 13:33:53 +02:00
end
end
end