importo 2.0.5 → 3.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -5
  3. data/Rakefile +16 -17
  4. data/app/controllers/concerns/maintenance_standards.rb +1 -1
  5. data/app/controllers/importo/imports_controller.rb +15 -12
  6. data/app/helpers/importo/application_helper.rb +11 -11
  7. data/app/importers/concerns/exportable.rb +31 -24
  8. data/app/importers/concerns/importable.rb +144 -62
  9. data/app/importers/concerns/importer_dsl.rb +6 -14
  10. data/app/importers/concerns/original.rb +23 -23
  11. data/app/importers/concerns/result_feedback.rb +62 -44
  12. data/app/importers/concerns/revertable.rb +11 -12
  13. data/app/importers/importo/base_importer.rb +16 -4
  14. data/app/importers/importo/import_job_callback.rb +29 -0
  15. data/app/jobs/importo/import_job.rb +40 -0
  16. data/app/mailers/importo/application_mailer.rb +2 -2
  17. data/app/models/importo/import.rb +35 -8
  18. data/app/models/importo/result.rb +5 -0
  19. data/app/services/importo/import_service.rb +1 -3
  20. data/app/services/importo/revert_service.rb +1 -1
  21. data/app/tables/importo/imports_table.rb +13 -17
  22. data/app/tables/importo/mensa_imports_table.rb +35 -0
  23. data/app/views/importo/imports/index.html.slim +6 -2
  24. data/app/views/importo/imports/new.html.slim +30 -20
  25. data/config/locales/en.yml +21 -9
  26. data/config/locales/nl.yml +10 -4
  27. data/config/routes.rb +4 -4
  28. data/db/migrate/20180409151031_create_importo_import.rb +9 -9
  29. data/db/migrate/20180628175535_add_locale_importo_import.rb +1 -1
  30. data/db/migrate/20230510051447_remove_result_from_imports.rb +5 -0
  31. data/db/migrate/20230510083043_create_importo_results.rb +11 -0
  32. data/lib/generators/importo/importer_generator.rb +1 -1
  33. data/lib/generators/importo/install_generator.rb +7 -8
  34. data/lib/generators/importo/templates/importo.rb +11 -0
  35. data/lib/generators/satis/install_generator.rb +22 -0
  36. data/lib/generators/satis/tailwind_config_generator.rb +24 -0
  37. data/lib/generators/satis/templates/config/initializers/satis.rb +13 -0
  38. data/lib/importo/acts_as_import_owner.rb +1 -1
  39. data/lib/importo/configuration.rb +52 -49
  40. data/lib/importo/engine.rb +11 -9
  41. data/lib/importo/import_column.rb +18 -6
  42. data/lib/importo/test_helpers.rb +19 -0
  43. data/lib/importo/version.rb +1 -1
  44. data/lib/importo.rb +12 -17
  45. metadata +75 -24
  46. data/app/services/importo/callback_service.rb +0 -14
  47. data/lib/generators/templates/importo.rb +0 -21
  48. /data/lib/generators/{templates → importo/templates}/README +0 -0
  49. /data/lib/generators/{templates → importo/templates}/application_importer.rb +0 -0
  50. /data/lib/generators/{templates → importo/templates}/importer.rb +0 -0
@@ -1,24 +1,34 @@
1
- = sts.form_for(@import) do |f|
2
- = f.input :kind, as: :hidden
3
- = sts.card title: t('.title'), icon: 'fad fa-file-spreadsheet' do |card|
4
- - card.action
5
- = f.submit
1
+ .grid.grid-cols-1.gap-4.sm:grid-cols-3.mt-4
2
+ .col-span-3.sm:col-span-3
3
+ = sts.form_for(@import) do |f|
4
+ = f.input :kind, as: :hidden
5
+ = sts.card :"importo_imports #{@import.kind}", title: t('.title'), icon: 'fad fa-file-spreadsheet' do |card|
6
+ - card.with_action
7
+ = f.submit
6
8
 
7
- .grid.grid-cols-12.gap-4
8
- .col-span-12
9
- .prose
10
- p= t('.explanation_html', name: @import.importer.class.friendly_name, sample_path: sample_import_path(kind: @import.kind))
11
- - if @import.allow_export?
12
- p= t('.export_html', export_path: export_path(kind: @import.kind))
9
+ .grid.grid-cols-12.gap-4
10
+ .col-span-12
11
+ .prose
12
+ p= t('.explanation_html', name: @import.importer.class.friendly_name, sample_path: sample_import_path(kind: @import.kind))
13
+ - if @import.allow_export?
14
+ p= t('.export_html', export_path: export_path(kind: @import.kind))
13
15
 
14
- .col-span-12
15
- - @import.importer.overridable_columns.each do |column|
16
- = f.fields_for :column_overrides do |fff|
17
- - if column.collection
18
- = fff.input column.attribute, as: :select, label: column.name, collection: column.collection, include_blank: true, required: false
19
- - else
20
- = fff.input column.attribute, label: column.name, required: false
16
+ .col-span-12
17
+ - @import.importer.overridable_columns.each do |column|
18
+ = f.fields_for :column_overrides do |fff|
19
+ - if column.collection
20
+ = fff.input column.attribute, as: :select, label: column.name, collection: column.collection, include_blank: true, required: false
21
+ - else
22
+ = fff.input column.attribute, label: column.name, required: false
21
23
 
22
- .col-span-12
23
- = f.input :original, as: :file
24
+ .col-span-12
25
+ = f.input :original, as: :file
26
+
27
+ .grid.grid-cols-1.gap-4.sm:grid-cols-3.mt-4
28
+ .col-span-3.sm:col-span-3
29
+ = sts.card :importo_imports, title: "#{@import.kind.humanize} imports", icon: 'fad fa-file-import', content_padding: false do |card|
30
+ - if defined? Mensa
31
+ = sts.mensa(:importo_mensa_imports, parameters: { kind: @import.kind })
32
+ - else
33
+ = card.with_table(:importo_imports, parameters: { kind: @import.kind }, custom_views: false)
24
34
 
@@ -1,8 +1,8 @@
1
1
  en:
2
2
  helpers:
3
- submit:
4
- importo/import:
5
- create: "Import"
3
+ submit:
4
+ importo/import:
5
+ create: "Import"
6
6
  importo:
7
7
  sheet:
8
8
  results:
@@ -10,24 +10,36 @@ en:
10
10
  explanation:
11
11
  name: Explanation
12
12
  column: Column
13
- explanation: Explanation
13
+ value: Value
14
+ explanation: Purpose
15
+ example: Example
14
16
  imports:
15
17
  index:
16
18
  title: Import results
19
+ card:
20
+ importo_imports:
21
+ title: Import results
22
+ tab:
23
+ Imports: Imports
17
24
  new:
18
- submit: 'Import'
25
+ submit: "Import"
19
26
  title: Import
20
27
  explanation_html: A CSV or Excel file can be used to import records. The first row should be the column names.<br>If an <b>id</b> is supplied it will update the matching record instead of creating a new one.<br>Download a <a href='%{sample_path}' target='_blank'>sample template</a> with all supported column names and their explanation.
21
28
  export_html: You can download the currently stored records.<br>Download the <a href='%{export_path}' target='_blank'>current data</a> with all supported columns
22
- error_explanation: 'The following problems prohibited this import from completing:'
29
+ error_explanation: "The following problems prohibited this import from completing:"
23
30
  import: Import %{kind}
24
31
  import_button: Import
32
+ card:
33
+ importo_imports:
34
+ tab:
35
+ importo_imports: Imports
25
36
  create:
26
37
  flash:
27
38
  no_file: Import failed, please upload a file.
28
- error: Import failed, there were problems.
29
- success: 'Import scheduled with id %{id}, you will get an email with the results.'
39
+ error: Import failed, there were problems %{error}.
40
+ success: "Import scheduled with id %{id}, you will get an email with the results."
30
41
  errors:
31
- structure_invalid: 'The structure is invalid, these are the invalid headers: %{invalid_headers}'
42
+ parse_error: "We encountered a parse error: %{error}"
43
+ structure_invalid: "The structure is invalid, these are the invalid headers: %{invalid_headers}"
32
44
  importers:
33
45
  result_message: "Successfully imported %{nr} of %{of} rows"
@@ -6,23 +6,29 @@ nl:
6
6
  explanation:
7
7
  name: Uitleg
8
8
  column: Kolom
9
- explanation: Uitleg
9
+ value: Waarde
10
+ explanation: Doeleinde
11
+ example: Voorbeeld
10
12
  imports:
11
13
  index:
12
14
  title: Import resultaten
15
+ card:
16
+ importo_imports:
17
+ title: Imports
13
18
  new:
14
19
  import:
15
20
  title: Importeer
16
21
  explanation_html: Een CSV of Excel bestand kan gebruikt worden om records te importeren. De eerste rij moet de kolom namen bevatten.<br>Als een <b>id</b> is ingevuld, zal het bestaande record worden geupdate in plaats van een nieuwe aan te maken.<br>Download een <a href='%{sample_path}' target='_blank'>voorbeeld file</a> met alle ondersteunde kolomnamen en de bijbehorende uitleg.
17
- error_explanation: 'De import is mislukt door de volgende problemen:'
22
+ error_explanation: "De import is mislukt door de volgende problemen:"
18
23
  import: Import %{kind}
19
24
  import_button: Importeer
20
25
  create:
21
26
  flash:
22
27
  no_file: Import mislukt, upload een bestand.
23
28
  error: Import mislukt, er waren problemen, voor details zie hieronder.
24
- success: 'Import geplanned met id %{id}, je krijgt een email met de resultaten.'
29
+ success: "Import geplanned met id %{id}, je krijgt een email met de resultaten."
25
30
  errors:
26
- structure_invalid: 'The structuur is ongeldig, dit zijn de ongeldige headers: %{invalid_headers}'
31
+ parse_error: "We ondervonden een parse error: %{error}"
32
+ structure_invalid: "The structuur is ongeldig, dit zijn de ongeldige headers: %{invalid_headers}"
27
33
  importers:
28
34
  result_message: "%{nr} van %{of} rijen succesvol geimporteerd"
data/config/routes.rb CHANGED
@@ -6,8 +6,8 @@ Importo::Engine.routes.draw do
6
6
  post :undo
7
7
  end
8
8
  end
9
- get ':kind/new', to: 'imports#new', as: :new_import
10
- get ':kind/sample', to: 'imports#sample', as: :sample_import
11
- get ':kind/export', to: 'imports#export', as: :export
12
- root to: 'imports#index'
9
+ get ":kind/new", to: "imports#new", as: :new_import
10
+ get ":kind/sample", to: "imports#sample", as: :sample_import
11
+ get ":kind/export", to: "imports#export", as: :export
12
+ root to: "imports#index"
13
13
  end
@@ -1,19 +1,19 @@
1
1
  class CreateImportoImport < ActiveRecord::Migration[5.1]
2
2
  def change
3
- enable_extension 'uuid-ossp'
4
- enable_extension 'pgcrypto'
3
+ enable_extension "uuid-ossp"
4
+ enable_extension "pgcrypto"
5
5
 
6
6
  return if table_exists?(:importo_imports)
7
7
 
8
8
  create_table :importo_imports, id: :uuid do |t|
9
- t.string :importo_ownable_type, null: false
10
- t.uuid :importo_ownable_id, null: false
9
+ t.string :importo_ownable_type, null: false
10
+ t.uuid :importo_ownable_id, null: false
11
11
 
12
- t.string :kind
13
- t.string :state
14
- t.string :file_name
15
- t.string :result_message
16
- t.jsonb :results
12
+ t.string :kind
13
+ t.string :state
14
+ t.string :file_name
15
+ t.string :result_message
16
+ t.jsonb :results
17
17
 
18
18
  t.timestamps
19
19
  end
@@ -2,6 +2,6 @@ class AddLocaleImportoImport < ActiveRecord::Migration[5.1]
2
2
  def change
3
3
  return if column_exists?(:importo_imports, :locale)
4
4
 
5
- add_column :importo_imports, :locale, :string, default: 'en'
5
+ add_column :importo_imports, :locale, :string, default: "en"
6
6
  end
7
7
  end
@@ -0,0 +1,5 @@
1
+ class RemoveResultFromImports < ActiveRecord::Migration[7.0]
2
+ def change
3
+ remove_column :importo_imports, :results, :jsonb
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class CreateImportoResults < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :importo_results, id: :uuid do |t|
4
+ t.integer :row_index
5
+ t.references :import, type: :uuid, null: false, foreign_key: {to_table: :importo_imports}
6
+ t.jsonb :details, default: {}
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -1,6 +1,6 @@
1
1
  module Importo
2
2
  class ImporterGenerator < Rails::Generators::NamedBase
3
- source_root File.expand_path('../templates', __FILE__)
3
+ source_root File.expand_path("templates", __dir__)
4
4
 
5
5
  def copy_initializer_file
6
6
  template "application_importer.rb", "app/importers/application_importer.rb"
@@ -1,26 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails/generators/base'
3
+ require "rails/generators/base"
4
4
 
5
5
  module Importo
6
6
  module Generators
7
-
8
7
  class InstallGenerator < Rails::Generators::Base
9
- source_root File.expand_path('../templates', __dir__)
8
+ source_root File.expand_path("../templates", __dir__)
10
9
 
11
- desc 'Creates a Importo initializer and copy locale files to your application.'
10
+ desc "Creates a Importo initializer and copy locale files to your application."
12
11
 
13
12
  def copy_initializer
14
- template 'importo.rb', 'config/initializers/importo.rb'
13
+ template "importo.rb", "config/initializers/importo.rb"
15
14
  end
16
15
 
17
16
  def copy_locale
18
- copy_file '../../../config/locales/en.yml', 'config/locales/importo.en.yml'
19
- copy_file '../../../config/locales/nl.yml', 'config/locales/importo.nl.yml'
17
+ copy_file "../../../config/locales/en.yml", "config/locales/importo.en.yml"
18
+ copy_file "../../../config/locales/nl.yml", "config/locales/importo.nl.yml"
20
19
  end
21
20
 
22
21
  def show_readme
23
- readme 'README' if behavior == :invoke
22
+ readme "README" if behavior == :invoke
24
23
  end
25
24
  end
26
25
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ Importo.setup do |config|
4
+ config.base_controller = "::ApplicationController"
5
+ config.admin_authentication_module = "Authenticated"
6
+
7
+ # Current import owner
8
+ config.current_import_owner = -> { Current.user }
9
+
10
+ config.queue_name = :import
11
+ end
@@ -0,0 +1,22 @@
1
+ module Satis
2
+ class InstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ def create_initializer_file
6
+ template "config/initializers/satis.rb"
7
+ end
8
+
9
+ def add_route
10
+ return if Rails.application.routes.routes.detect { |route| route.app.app == Satis::Engine }
11
+ route %(mount Satis::Engine => "/satis")
12
+ end
13
+
14
+ def copy_migrations
15
+ rake "satis:install:migrations"
16
+ end
17
+
18
+ def tailwindcss_config
19
+ rake "satis:tailwindcss:config"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require "rails/generators/base"
2
+
3
+ module Satis
4
+ module Generators
5
+ class TailwindConfigGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../templates", __dir__)
7
+ desc "Configures tailwind.config.js and application.tailwindcss.css"
8
+
9
+ def add_content_to_tailwind_config
10
+ inject_into_file "config/tailwind.config.js", before: "],\n theme: {" do
11
+ " // Satis content\n" +
12
+ %w[/app/views/**/* /app/helpers/**/* /app/controllers/**/* /app/components/**/* /app/javascript/**/*.js /app/assets/**/*.css].map { |path| " \"#{Satis::Engine.root}#{path}\"" }.join(",\n") +
13
+ ",\n "
14
+ end
15
+ end
16
+
17
+ def add_content_application_tailwind_css
18
+ inject_into_file "app/assets/stylesheets/application.tailwind.css", before: "@tailwind base;" do
19
+ "@import '#{Satis::Engine.root}/app/assets/stylesheets/satis/application.css';\n"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ Satis.setup do |config|
4
+ config.submit_on_enter = false
5
+
6
+ config.logger = Rails.logger
7
+ config.confirm_before_leave = false
8
+ config.current_user = -> { Current.user }
9
+
10
+ config.default_help_text = lambda do |template, object, key, additional_scope|
11
+ I18n.t((["help"] + [key.to_s]).join("."), default: nil)
12
+ end
13
+ end
@@ -5,7 +5,7 @@ module Importo
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- has_many :import, as: :importo_ownable, class_name: 'Importo::Import'
8
+ has_many :import, as: :importo_ownable, class_name: "Importo::Import"
9
9
  end
10
10
  end
11
11
  end
@@ -1,68 +1,71 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Importo
4
- class Configuration
5
- attr_accessor :admin_authentication_module
6
- attr_accessor :base_controller
7
- attr_accessor :base_service
8
- attr_accessor :base_service_context
9
- attr_accessor :queue_name
10
-
11
- attr_writer :logger
12
- attr_writer :current_import_owner
13
- attr_writer :import_callbacks
14
- attr_writer :admin_visible_imports
15
- attr_writer :admin_can_destroy
16
- attr_writer :admin_extra_links
17
-
18
- def initialize
19
- @logger = Logger.new(STDOUT)
20
- @logger.level = Logger::INFO
21
- @base_controller = '::ApplicationController'
22
- @base_service = '::ApplicationService'
23
- @base_service_context = '::ApplicationContext'
24
- @current_import_owner = -> {}
25
- @import_callbacks = {
26
- importing: lambda do |_import|
27
- end,
28
- completed: lambda do |_import|
29
- end,
30
- failed: lambda do |_import|
31
- end
32
- }
33
- @queue_name = :import
4
+ module Options
5
+ module ClassMethods
6
+ def option(name, default: nil)
7
+ attr_accessor(name)
8
+ schema[name] = default
9
+ end
34
10
 
35
- @admin_visible_imports = -> { Importo::Import.where(importo_ownable: current_import_owner) }
36
- @admin_can_destroy = ->(_import) { false }
37
-
38
- # Extra links relevant for this import: { link_name: { icon: 'far fa-..', url: '...' } }
39
- @admin_extra_links = ->(_import) { }
11
+ def schema
12
+ @schema ||= {}
13
+ end
40
14
  end
41
15
 
42
- # Config: logger [Object].
43
- def logger
44
- @logger.is_a?(Proc) ? instance_exec(&@logger) : @logger
16
+ def set_defaults!
17
+ self.class.schema.each do |name, default|
18
+ instance_variable_set(:"@#{name}", default)
19
+ end
45
20
  end
46
21
 
47
- def current_import_owner
48
- raise 'current_import_owner should be a Proc' unless @current_import_owner.is_a? Proc
49
- instance_exec(&@current_import_owner)
22
+ def self.included(cls)
23
+ cls.extend(ClassMethods)
50
24
  end
25
+ end
26
+
27
+ class Configuration
28
+ include Options
29
+
30
+ option :logger, default: Rails.logger
31
+ option :admin_authentication_module
32
+ option :base_controller, default: "::ApplicationController"
33
+ option :base_service, default: "::ApplicationService"
34
+ option :base_service_context, default: "::ApplicationContext"
35
+ option :current_import_owner, default: lambda {}
36
+ option :queue_name, default: :import
37
+
38
+ option :admin_visible_imports, default: lambda { Importo::Import.where(importo_ownable: Importo.config.current_import_owner) }
39
+ option(:admin_can_destroy,
40
+ default: lambda do |import|
41
+ false
42
+ end)
43
+
44
+ # Extra links relevant for this import: { link_name: { icon: 'far fa-..', url: '...' } }
45
+ option(:admin_extra_links,
46
+ default: lambda do |import|
47
+ []
48
+ end)
51
49
 
52
- def import_callback(import, state)
53
- instance_exec(import, &@import_callbacks[state]) if @import_callbacks[state]
50
+ def initialize
51
+ set_defaults!
54
52
  end
53
+ end
54
+
55
+ module Configurable
56
+ attr_writer :config
55
57
 
56
- def admin_visible_imports
57
- instance_exec(&@admin_visible_imports) if @admin_visible_imports
58
+ def config
59
+ @config ||= Configuration.new
58
60
  end
59
61
 
60
- def admin_can_destroy(import)
61
- instance_exec(import, &@admin_can_destroy) if @admin_can_destroy
62
+ def configure
63
+ yield(config)
62
64
  end
65
+ alias_method :setup, :configure
63
66
 
64
- def admin_extra_links(import)
65
- instance_exec(import, &@admin_extra_links) if @admin_extra_links
67
+ def reset_config!
68
+ @config = Configuration.new
66
69
  end
67
70
  end
68
71
  end
@@ -1,23 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "axlsx"
4
+ require "roo"
5
+ require "roo-xls"
6
+ require "slim"
7
+ require "state_machines-activerecord"
8
+ require "signum"
9
+ require "turbo-rails"
10
+ require "view_component"
11
+ require "with_advisory_lock"
12
+
3
13
  module Importo
4
14
  class Engine < ::Rails::Engine
5
15
  isolate_namespace Importo
6
16
 
7
- initializer 'importo.active_storage.attached' do
17
+ initializer "importo.active_storage.attached" do
8
18
  config.after_initialize do
9
19
  ActiveSupport.on_load(:active_record) do
10
20
  Importo::Import.include(ImportHelpers)
11
21
  end
12
22
  end
13
23
  end
14
-
15
- initializer 'importo.append_migrations' do |app|
16
- unless app.root.to_s.match?(root.to_s)
17
- config.paths['db/migrate'].expanded.each do |expanded_path|
18
- app.config.paths['db/migrate'] << expanded_path
19
- end
20
- end
21
- end
22
24
  end
23
25
  end
@@ -3,12 +3,12 @@
3
3
  module Importo
4
4
  class ImportColumn
5
5
  attr_accessor :proc, :options
6
- attr_writer :name, :hint, :explanation
6
+ attr_writer :name, :hint, :explanation, :value, :example
7
7
 
8
- def initialize(name, hint, explanation, options, &block)
8
+ def initialize(name: nil, **options, &block)
9
9
  @name = name
10
- @hint = hint
11
- @explanation = explanation
10
+ @hint = options[:hint]
11
+ @explanation = options[:explanation]
12
12
  @options = options || {}
13
13
  @proc = block
14
14
  end
@@ -33,11 +33,19 @@ module Importo
33
33
  end
34
34
 
35
35
  def hint
36
- I18n.t(".hint.#{options[:attribute]}", scope: [:importers, options[:scope]], default: '') if options[:attribute]
36
+ I18n.t(".hint.#{options[:attribute]}", scope: [:importers, options[:scope]], default: "") if options[:attribute]
37
37
  end
38
38
 
39
39
  def explanation
40
- I18n.t(".explanation.#{options[:attribute]}", scope: [:importers, options[:scope]], default: '') if options[:attribute]
40
+ I18n.t(".explanation.#{options[:attribute]}", scope: [:importers, options[:scope]], default: "") if options[:attribute]
41
+ end
42
+
43
+ def value
44
+ I18n.t(".value.#{options[:attribute]}", scope: [:importers, options[:scope]], default: "") if options[:attribute]
45
+ end
46
+
47
+ def example
48
+ I18n.t(".example.#{options[:attribute]}", scope: [:importers, options[:scope]], default: "") if options[:attribute]
41
49
  end
42
50
 
43
51
  ##
@@ -51,5 +59,9 @@ module Importo
51
59
  def collection
52
60
  options[:collection]
53
61
  end
62
+
63
+ def delay
64
+ options[:delay]
65
+ end
54
66
  end
55
67
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "axlsx"
4
+
5
+ module Importo
6
+ module TestHelpers
7
+ def simple_sheet(an_array, sheet_name: "Import")
8
+ xls = Axlsx::Package.new
9
+ workbook = xls.workbook
10
+ sheet = workbook.add_worksheet(name: sheet_name)
11
+
12
+ an_array.each do |a|
13
+ sheet.add_row a
14
+ end
15
+
16
+ xls.to_stream
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Importo
4
- VERSION = "2.0.5"
4
+ VERSION = "3.0.10"
5
5
  end
data/lib/importo.rb CHANGED
@@ -1,29 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'axlsx'
4
- require 'roo'
5
- require 'roo-xls'
6
- require 'slim'
7
- require 'state_machines-activerecord'
8
- # require 'active_storage/downloading'
9
-
10
- require_relative 'importo/engine'
11
- require_relative 'importo/acts_as_import_owner'
12
- require_relative 'importo/import_column'
13
- require_relative 'importo/import_helpers'
14
- require_relative 'importo/configuration'
3
+ require_relative "importo/engine"
4
+ require_relative "importo/acts_as_import_owner"
5
+ require_relative "importo/import_column"
6
+ require_relative "importo/import_helpers"
7
+ require_relative "importo/configuration"
15
8
 
16
9
  module Importo
10
+ extend Configurable
11
+
17
12
  class Error < StandardError; end
18
13
 
19
14
  class DuplicateRowError < Error; end
20
15
 
21
- class << self
22
- attr_reader :config
16
+ class RetryError < StandardError
17
+ attr_reader :delay
23
18
 
24
- def setup
25
- @config = Configuration.new
26
- yield config
19
+ def initialize(msg, delay)
20
+ super(msg)
21
+ @delay = delay
27
22
  end
28
23
  end
29
24
  end