add stamp field type
This commit is contained in:
+15
-3
@@ -9,14 +9,26 @@ module PdfIcons
|
||||
module_function
|
||||
|
||||
def check_io
|
||||
@check_io ||= StringIO.new(PATH.join('check.png').read)
|
||||
StringIO.new(check_data)
|
||||
end
|
||||
|
||||
def paperclip_io
|
||||
@paperclip_io ||= StringIO.new(PATH.join('paperclip.png').read)
|
||||
StringIO.new(paperclip_data)
|
||||
end
|
||||
|
||||
def logo_io
|
||||
@logo_io ||= StringIO.new(PATH.join('logo.png').read)
|
||||
StringIO.new(logo_data)
|
||||
end
|
||||
|
||||
def check_data
|
||||
@check_data ||= PATH.join('check.png').read
|
||||
end
|
||||
|
||||
def paperclip_data
|
||||
@paperclip_data ||= PATH.join('paperclip.png').read
|
||||
end
|
||||
|
||||
def logo_data
|
||||
@logo_data ||= PATH.join('logo.png').read
|
||||
end
|
||||
end
|
||||
|
||||
@@ -192,7 +192,7 @@ module Submissions
|
||||
}
|
||||
].compact_blank, line_spacing: 1.8, padding: [0, 0, 5, 0]
|
||||
),
|
||||
if field['type'].in?(%w[image signature initials])
|
||||
if field['type'].in?(%w[image signature initials stamp])
|
||||
attachment = submitter.attachments.find { |a| a.uuid == value }
|
||||
image = Vips::Image.new_from_buffer(attachment.download, '').autorot
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ module Submissions
|
||||
canvas.font(FONT_NAME, size: font_size)
|
||||
|
||||
case field['type']
|
||||
when 'image', 'signature', 'initials'
|
||||
when 'image', 'signature', 'initials', 'stamp'
|
||||
attachment = submitter.attachments.find { |a| a.uuid == value }
|
||||
|
||||
image = Vips::Image.new_from_buffer(attachment.download, '').autorot
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Submitters
|
||||
module CreateStampAttachment
|
||||
WIDTH = 400
|
||||
HEIGHT = 200
|
||||
|
||||
TRANSPARENT_PIXEL = "\x89PNG\r\n\u001A\n\u0000\u0000\u0000\rIHDR\u0000" \
|
||||
"\u0000\u0000\u0001\u0000\u0000\u0000\u0001\b\u0004" \
|
||||
"\u0000\u0000\u0000\xB5\u001C\f\u0002\u0000\u0000\u0000" \
|
||||
"\vIDATx\xDAc\xFC_\u000F\u0000\u0002\x83\u0001\x804\xC3ڨ" \
|
||||
"\u0000\u0000\u0000\u0000IEND\xAEB`\x82"
|
||||
|
||||
module_function
|
||||
|
||||
def call(submitter)
|
||||
image = generate_stamp_image(submitter)
|
||||
|
||||
image_data = image.write_to_buffer('.png')
|
||||
|
||||
checksum = Digest::MD5.base64digest(image_data)
|
||||
|
||||
attachment = submitter.attachments.joins(:blob).find_by(blob: { checksum: })
|
||||
|
||||
attachment || ActiveStorage::Attachment.create!(
|
||||
blob: ActiveStorage::Blob.create_and_upload!(io: StringIO.new(image_data), filename: 'stamp.png'),
|
||||
metadata: { analyzed: true, identified: true, width: image.width, height: image.height },
|
||||
name: 'attachments',
|
||||
record: submitter
|
||||
)
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics
|
||||
def generate_stamp_image(submitter)
|
||||
logo = Vips::Image.new_from_buffer(load_logo(submitter).read, '')
|
||||
|
||||
logo = logo.resize([WIDTH / logo.width.to_f, HEIGHT / logo.height.to_f].min)
|
||||
|
||||
base_layer = Vips::Image.black(WIDTH, HEIGHT).new_from_image([255, 255, 255]).copy(interpretation: :srgb)
|
||||
|
||||
opacity_layer = Vips::Image.new_from_buffer(TRANSPARENT_PIXEL, '').resize(WIDTH)
|
||||
|
||||
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
|
||||
# rubocop:enable Metrics
|
||||
|
||||
def build_text_image(submitter)
|
||||
time = I18n.l(submitter.completed_at.in_time_zone(submitter.account.timezone), format: :long,
|
||||
locale: submitter.account.locale)
|
||||
|
||||
timezone = TimeUtils.timezone_abbr(submitter.account.timezone, submitter.completed_at)
|
||||
|
||||
name = if submitter.name.present? && submitter.email.present?
|
||||
"#{submitter.name} #{submitter.email}"
|
||||
else
|
||||
submitter.name || submitter.email || submitter.phone
|
||||
end
|
||||
|
||||
role = if submitter.submission.template_submitters.size > 1
|
||||
item = submitter.submission.template_submitters.find { |e| e['uuid'] == submitter.uuid }
|
||||
|
||||
"Role: #{item['name']}\n"
|
||||
else
|
||||
''
|
||||
end
|
||||
|
||||
text = %(<span size="90">Digitally signed by: <b>#{name}</b>\n#{role}#{time} #{timezone}</span>)
|
||||
|
||||
Vips::Image.text(text, width: WIDTH, height: HEIGHT)
|
||||
end
|
||||
|
||||
def load_logo(_submitter)
|
||||
PdfIcons.logo_io
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -74,6 +74,12 @@ module Submitters
|
||||
default_values = submitter.submission.template_fields.each_with_object({}) do |field, acc|
|
||||
next if field['submitter_uuid'] != submitter.uuid
|
||||
|
||||
if field['type'] == 'stamp'
|
||||
acc[field['uuid']] ||= Submitters::CreateStampAttachment.call(submitter).uuid
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
value = field['default_value']
|
||||
|
||||
next if value.blank?
|
||||
|
||||
Reference in New Issue
Block a user