Class: GeneratedPdfImporter

Inherits:
Object
  • Object
show all
Defined in:
app/services/generated_pdf_importer.rb

Overview

Promotes a pending GeneratedPdf into the publication library — a Literature
upload + a publication Item — and persists the declarative +layout+ onto the
Literature (+uploads.source_layout+) so the published PDF can be re-opened and
iterated later.

The PDF analogue of GeneratedImageImporter. Three modes, chosen in the studio:
:new — create a brand-new publication (no source publication)
:replace — swap the staged PDF onto an existing publication in place (same SKU)
:revise — create the next revision (-A → -B) via Publication::Reviser, with
the staged PDF as the new revision's Literature

Routing through Publication::Saver / Publication::Reviser means the existing
after_commit pipeline (cover image, search_text, PublicationVisionWorker,
EmbeddingWorker) fires for free.

Usage:
GeneratedPdfImporter.call(gen, base_name: "Spec Sheet", sku: "TZ-SPEC-A") # new
GeneratedPdfImporter.call(gen, mode: :revise) # revise source_publication

Defined Under Namespace

Classes: Failed, Result

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(generated_pdf, mode: nil, base_name: nil, sku: nil, category_id: nil, locales: nil, notes: nil) ⇒ GeneratedPdfImporter

Returns a new instance of GeneratedPdfImporter.



40
41
42
43
44
45
46
47
48
# File 'app/services/generated_pdf_importer.rb', line 40

def initialize(generated_pdf, mode: nil, base_name: nil, sku: nil, category_id: nil, locales: nil, notes: nil)
  @gen         = generated_pdf
  @mode        = mode&.to_sym
  @base_name   = base_name.to_s.strip
  @sku         = sku.presence
  @category_id = category_id
  @locales     = Array(locales).compact_blank.presence || %w[en]
  @notes       = notes
end

Class Method Details

.call(generated_pdf, mode: nil, base_name: nil, sku: nil, category_id: nil, locales: nil, notes: nil) ⇒ Result

Parameters:

  • generated_pdf (GeneratedPdf)
  • mode (Symbol, String, nil) (defaults to: nil)

    :new (default when no source) / :replace / :revise

  • base_name (String, nil) (defaults to: nil)

    publication_base_name (required for :new)

  • sku (String, nil) (defaults to: nil)

    publication SKU (revision-lettered); derived for :new if blank

  • category_id (Integer, nil) (defaults to: nil)

    ProductCategory id; defaults to the publications root

  • locales (Array<String>, nil) (defaults to: nil)

    publication_locales; defaults to ["en"]

  • notes (String, nil) (defaults to: nil)

Returns:



36
37
38
# File 'app/services/generated_pdf_importer.rb', line 36

def self.call(generated_pdf, mode: nil, base_name: nil, sku: nil, category_id: nil, locales: nil, notes: nil)
  new(generated_pdf, mode:, base_name:, sku:, category_id:, locales:, notes:).call
end

Instance Method Details

#callObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'app/services/generated_pdf_importer.rb', line 50

def call
  return Result.new(error: 'Only a pending PDF can be imported.') unless @gen.pending?
  return Result.new(error: 'No staged PDF to import.') unless @gen.file_stored?

  mode = resolved_mode
  return Result.new(error: 'A publication name is required.') if mode == :new && @base_name.blank?

  # Advisory lock so a double-submit (or retry) can't import the same staged
  # PDF twice and create duplicate publications.
  result = @gen.with_advisory_lock("import_generated_pdf_#{@gen.id}", timeout_seconds: 0) do
    perform_import(mode)
  end
  result == false ? Result.new(error: 'An import is already in progress for this PDF.') : result
rescue Failed => e
  Result.new(error: e.message)
rescue StandardError => e
  Rails.logger.error "[GeneratedPdfImporter] #{e.class}: #{e.message}"
  ErrorReporting.error(e) if defined?(ErrorReporting)
  Result.new(error: e.message)
end