Class: DocumentTemplate

Inherits:
Ekylibre::Record::Base show all
Defined in:
app/models/document_template.rb

Overview

Sources are stored in :private/reporting/:id/content.xml

Constant Summary collapse

@@load_path =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Ekylibre::Record::Base

#already_updated?, #check_if_destroyable?, #check_if_updateable?, columns_definition, #customizable?, customizable?, #customized?, #destroyable?, #editable?, has_picture, #human_attribute_name, nomenclature_reflections, #old_record, #others, refers_to, #unsuppress, #updateable?

Methods included from Userstamp::Stampable

included

Methods included from Userstamp::Stamper

included

Instance Attribute Details

#sourceObject

Returns source value


148
149
150
# File 'app/models/document_template.rb', line 148

def source
  @source
end

Class Method Details

.load_defaults(options = {}) ⇒ Object

Loads in DB all default document templates


270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'app/models/document_template.rb', line 270

def load_defaults(options = {})
  locale = (options[:locale] || Preference[:language] || I18n.locale).to_s
  Ekylibre::Record::Base.transaction do
    manageds = where(managed: true).select(&:destroyable?)
    nature.values.each do |nature|
      if source = template_fallbacks(nature, locale).detect(&:exist?)
        File.open(source, 'rb:UTF-8') do |f|
          unless template = find_by(nature: nature, managed: true)
            template = new(nature: nature, managed: true, active: true, by_default: false, archiving: 'last')
          end
          manageds.delete(template)
          template.attributes = { source: f, language: locale }
          template.name ||= template.nature.l
          template.save!
        end
        Rails.logger.info "Load a default document template #{nature}"
      else
        Rails.logger.warn "Cannot load a default document template #{nature}: No file found at #{source}"
      end
    end
    destroy(manageds.map(&:id))
  end
  true
end

Print document with default active template for the given nature Returns nil if no template found.


236
237
238
239
240
241
# File 'app/models/document_template.rb', line 236

def print(nature, datasource, key, format = :pdf, options = {})
  if template = find_by(nature: nature, by_default: true, active: true)
    return template.print(datasource, key, format, options)
  end
  nil
end

.sources_rootObject

Returns the root directory for the document templates's sources


244
245
246
# File 'app/models/document_template.rb', line 244

def sources_root
  Ekylibre::Tenant.private_directory.join('reporting')
end

.template_fallbacks(nature, locale) ⇒ Object

Compute fallback chain for a given document nature


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'app/models/document_template.rb', line 249

def template_fallbacks(nature, locale)
  stack = []
  load_path.each do |path|
    root = path.join(locale, 'reporting')
    stack << root.join("#{nature}.xml")
    stack << root.join("#{nature}.jrxml")
    fallback = {
      sales_order: :sale,
      sales_estimate: :sale,
      sales_invoice: :sale,
      purchases_estimate: :purchases_order
    }[nature.to_sym]
    if fallback
      stack << root.join("#{fallback}.xml")
      stack << root.join("#{fallback}.jrxml")
    end
  end
  stack
end

Instance Method Details

#document(data_or_path, key, _format, options = {}) ⇒ Object

Archive the document using the given archiving method


201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'app/models/document_template.rb', line 201

def document(data_or_path, key, _format, options = {})
  return nil if archiving_none? || archiving_none_of_template?

  # Gets historic of document
  archives = Document.where(nature: nature, key: key).where.not(template_id: nil)
  archives_of_template = archives.where(template_id: id)

  # Checks if archiving is expected
  return nil unless (archiving_first? && archives.empty?) ||
                    (archiving_first_of_template? && archives_of_template.empty?) ||
                    archiving.to_s =~ /\A(last|all)(\_of\_template)?\z/

  # Lists last documents to remove after archiving
  removables = []
  if archiving_last?
    removables = archives.pluck(:id)
  elsif archiving_last_of_template?
    removables = archives_of_template.pluck(:id)
  end

  # Creates document if not exist
  document = Document.create!(nature: nature, key: key, name: (options[:name] || tc('document_name', nature: nature.l, key: key)), file: File.open(data_or_path), template_id: id)

  # Removes useless docs
  Document.destroy removables

  document
end

#export(datasource, key, format = :pdf, options = {}) ⇒ Object

Export a document with the given datasource and return path file Store if needed by template

Parameters:

  • datasource

    XML representation of data used by the template


177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'app/models/document_template.rb', line 177

def export(datasource, key, format = :pdf, options = {})
  # Load the report
  report = Beardley::Report.new(source_path, locale: 'i18n.iso2'.t)
  # Call it with datasource
  path = Pathname.new(report.to_file(format.to_sym, datasource))
  # Archive the document according to archiving method. See #document method.
  if document = self.document(path, key, format, options)
    FileUtils.rm_rf(path)
    path = document.file.path(:original)
  end
  # Returns only the path
  path
end

#formatsObject

Returns the list of formats of the templates


192
193
194
# File 'app/models/document_template.rb', line 192

def formats
  (self['formats'].blank? ? Ekylibre::Reporting.formats : self['formats'].strip.split(/[\s\,]+/))
end

#formats=(value) ⇒ Object


196
197
198
# File 'app/models/document_template.rb', line 196

def formats=(value)
  self['formats'] = (value.is_a?(Array) ? value.join(', ') : value.to_s)
end

Print a document with the given datasource and return raw data Store if needed by template

Parameters:

  • datasource

    XML representation of data used by the template


163
164
165
166
167
168
169
170
171
172
# File 'app/models/document_template.rb', line 163

def print(datasource, key, format = :pdf, options = {})
  # Load the report
  report = Beardley::Report.new(source_path, locale: 'i18n.iso2'.t)
  # Call it with datasource
  data = report.send("to_#{format}", datasource)
  # Archive the document according to archiving method. See #document method.
  document(data, key, format, options)
  # Returns only the data (without filename)
  data
end

#source_dirObject

Returns the expected dir for the source file


151
152
153
# File 'app/models/document_template.rb', line 151

def source_dir
  self.class.sources_root.join(id.to_s)
end

#source_pathObject

Returns the expected path for the source file


156
157
158
# File 'app/models/document_template.rb', line 156

def source_path
  source_dir.join('content.xml')
end