Add export_item type

This commit is contained in:
simon lehericey 2024-07-18 09:57:23 +02:00
parent 24109a0128
commit 977cfc87ce
No known key found for this signature in database
GPG key ID: CDE670D827C7B3C5
5 changed files with 190 additions and 0 deletions

70
app/models/export_item.rb Normal file
View file

@ -0,0 +1,70 @@
class ExportItem
include TagsSubstitutionConcern
DOSSIER_STATE = Dossier.states.fetch(:en_construction)
FORMAT_DATE = "%Y-%m-%d".freeze
attr_reader :template, :enabled, :stable_id
def initialize(template:, enabled: true, stable_id: nil)
@template, @enabled, @stable_id = template, enabled, stable_id
end
def self.default(prefix:, enabled: true, stable_id: nil)
new(template: prefix_dossier_id(prefix), enabled:, stable_id:)
end
def self.default_pj(tdc)
default(prefix: tdc.libelle_as_filename, enabled: false, stable_id: tdc.stable_id)
end
def enabled? = enabled
def template_json = template.to_json
def template_string = TiptapService.new.to_path(template)
def path(dossier, attachment: nil, row_index: nil, index: nil)
used_tags = TiptapService.used_tags_and_libelle_for(template)
substitutions = tags_substitutions(used_tags, dossier, escape: false, memoize: true)
substitutions['original-filename'] = attachment.filename.base if attachment
TiptapService.new.to_path(template, substitutions) + suffix(attachment, row_index, index)
end
def ==(other)
self.class == other.class &&
template == other.template &&
enabled == other.enabled &&
stable_id == other.stable_id
end
private
def self.prefix_dossier_id(prefix)
{
type: "doc",
content: [
{
type: "paragraph",
content: [
{ text: "#{prefix}-", type: "text" },
{ type: "mention", attrs: DOSSIER_ID_TAG.slice(:id, :label) }
]
}
]
}
end
def suffix(attachment, row_index, index)
suffix = ""
suffix += "-#{add_one_and_pad(row_index)}" if row_index.present?
suffix += "-#{add_one_and_pad(index)}" if index.present?
suffix += attachment.filename.extension_with_delimiter if attachment
suffix
end
def add_one_and_pad(number)
(number + 1).to_s.rjust(2, '0') if number.present?
end
end

View file

@ -0,0 +1,40 @@
class ExportItemType < ActiveRecord::Type::Value
# form_input, or setter -> type
def cast(value)
value = value.deep_symbolize_keys if value.respond_to?(:deep_symbolize_keys)
case value
in ExportItem
value
in NilClass # default value
nil
# from db
in { template: Hash, enabled: TrueClass | FalseClass } => h
ExportItem.new(**h.slice(:template, :enabled, :stable_id))
# from form
in { template: String } => h
template = JSON.parse(h[:template]).deep_symbolize_keys
enabled = h[:enabled] == 'true'
stable_id = h[:stable_id]&.to_i
ExportItem.new(template:, enabled:, stable_id:)
end
end
# db -> ruby
def deserialize(value) = cast(value&.then { JSON.parse(_1) })
# ruby -> db
def serialize(value)
if value.is_a?(ExportItem)
JSON.generate({
template: value.template,
enabled: value.enabled,
stable_id: value.stable_id
}.compact)
else
raise ArgumentError, "Invalid value for ExportItem serialization: #{value}"
end
end
end

View file

@ -0,0 +1,5 @@
require Rails.root.join("app/types/export_item_type")
ActiveSupport.on_load(:active_record) do
ActiveRecord::Type.register(:export_item, ExportItemType)
end

View file

@ -0,0 +1,20 @@
describe ExportItem do
describe 'path' do
let(:export_item) { ExportItem.default(prefix: 'custom') }
let(:dossier) { create(:dossier) }
let(:attachment) do
ActiveStorage::Attachment.new(
name: 'filename',
blob: ActiveStorage::Blob.new(filename: "file.pdf")
)
end
context 'without index nor row_index' do
it do
expect(export_item.path(dossier, attachment:)).to eq("custom-#{dossier.id}.pdf")
expect(export_item.path(dossier, attachment:, index: 3)).to eq("custom-#{dossier.id}-04.pdf")
expect(export_item.path(dossier, attachment:, row_index: 2, index: 3)).to eq("custom-#{dossier.id}-03-04.pdf")
end
end
end
end

View file

@ -0,0 +1,55 @@
describe ExportItemType do
let(:type) { ExportItemType.new }
describe 'cast' do
it 'from ExportItem' do
export_item = ExportItem.new(template: { foo: 'bar' }, enabled: true, stable_id: 42)
expect(type.cast(export_item)).to eq(export_item)
end
it 'from nil' do
expect(type.cast(nil)).to eq(nil)
end
it 'from db' do
h = { template: { foo: 'bar' }, enabled: true, stable_id: 42 }
expect(type.cast(h)).to eq(ExportItem.new(template: { foo: 'bar' }, enabled: true, stable_id: 42))
end
it 'from form' do
h = { template: '{"foo":{"bar":"zob"}}' }
expect(type.cast(h)).to eq(ExportItem.new(template: { foo: { bar: 'zob' } }, enabled: false))
h = { template: '{"foo":{"bar":"zob"}}', enabled: 'true' }
expect(type.cast(h)).to eq(ExportItem.new(template: { foo: { bar: 'zob' } }, enabled: true))
h = { template: '{"foo":{"bar":"zob"}}', stable_id: '42' }
expect(type.cast(h)).to eq(ExportItem.new(template: { foo: { bar: 'zob' } }, enabled: false, stable_id: 42))
h = { template: '{"foo":{"bar":"zob"}}', enabled: 'true', stable_id: '42' }
expect(type.cast(h)).to eq(ExportItem.new(template: { foo: { bar: 'zob' } }, enabled: true, stable_id: 42))
end
it 'from invalid value' do
expect { type.cast('invalid value') }.to raise_error(NoMatchingPatternError)
end
end
describe 'deserialize' do
it 'from nil' do
expect(type.deserialize(nil)).to eq(nil)
end
it 'from db' do
h = { template: { foo: 'bar' }, enabled: true, stable_id: 42 }
expect(type.deserialize(JSON.generate(h))).to eq(ExportItem.new(template: { foo: 'bar' }, enabled: true, stable_id: 42))
end
end
describe 'serialize' do
it 'from ExportItem' do
export_item = ExportItem.new(template: { foo: 'bar' }, enabled: true, stable_id: 42)
expect(type.serialize(export_item)).to eq('{"template":{"foo":"bar"},"enabled":true,"stable_id":42}')
end
end
end