From 1d6e840d4c88ebc0bf4c8380a3a7bf7eb4d4fe15 Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Thu, 1 Oct 2020 16:53:32 +0000 Subject: [PATCH 01/22] Remove deprecation warnings Fix #888 --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b84d416d1c..e55373aedf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,8 @@ RUN apt-get update && \ apt-get autoremove -y && \ cp config/database.postgres.docker.yml config/database.yml && \ gem install bundler && \ - bundle install --deployment && \ + bundle config set deployment 'true' && \ + bundle install && \ bundle exec rails assets:precompile CMD ["bundle","exec","rails","s"] From 1e506a6995b8911b6f0e1547120b3be349a8d7d9 Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Thu, 5 Nov 2020 08:20:24 +0000 Subject: [PATCH 02/22] Add imported files --- app/models/files/imported_file.rb | 43 +++++++++++++++++++ config/initializers/file.rb | 15 +++++++ .../20201103150431_create_imported_files.rb | 16 +++++++ db/schema.rb | 9 +++- spec/factories/imported_files.rb | 6 +++ spec/models/files/imported_file_spec.rb | 21 +++++++++ 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 app/models/files/imported_file.rb create mode 100644 config/initializers/file.rb create mode 100644 db/migrate/20201103150431_create_imported_files.rb create mode 100644 spec/factories/imported_files.rb create mode 100644 spec/models/files/imported_file_spec.rb diff --git a/app/models/files/imported_file.rb b/app/models/files/imported_file.rb new file mode 100644 index 0000000000..ab2a12102d --- /dev/null +++ b/app/models/files/imported_file.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ +# == Schema Information +# +# Table name: imported_files +# +# id :integer not null, primary key +# filename :string(64) default(""), not null +# md5sum :string(32) default(""), not null +# + +class ImportedFile < ActiveRecord::Base + before_validation :generate_md5sum + + validate :filetype + + validates :filename, presence: true + validates :md5sum, presence: true + validates :md5sum, uniqueness: { message: "file already imported" } + + def generate_md5sum + self.md5sum = Digest::MD5.hexdigest File.open(filename).read unless filename.empty? rescue "" + end + + private + + def filetype + valid = File.open(filename).type_from_file_command == "text/xml" rescue "" + if valid == "" + errors.add(:filename, "no such file") + end + unless valid + errors.add(:filename, "invalid filetype") + end + end + + ActiveSupport.run_load_hooks(:fat_free_crm_imported_file, self) +end diff --git a/config/initializers/file.rb b/config/initializers/file.rb new file mode 100644 index 0000000000..c603f986af --- /dev/null +++ b/config/initializers/file.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ +File.class_eval do + def type_from_file_command + type = (self.original_filename.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase + mime_type = `file -b --mime-type #{self.path}`.split(':').last.strip rescue "application/x-#{type}" + mime_type = "application/x-#{type}" if mime_type.match(/\(.*?\)/) + mime_type + end +end diff --git a/db/migrate/20201103150431_create_imported_files.rb b/db/migrate/20201103150431_create_imported_files.rb new file mode 100644 index 0000000000..25af1acb8a --- /dev/null +++ b/db/migrate/20201103150431_create_imported_files.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class CreateImportedFiles < ActiveRecord::Migration[4.2] + def self.up + create_table :imported_files, force: true do |t| + t.string :filename, limit: 64, null: false, default: "" + t.string :md5sum, limit: 32, null: false, default: "" + + t.timestamps + end + end + + def self.down + drop_table :imported_files + end +end diff --git a/db/schema.rb b/db/schema.rb index 9fff439ce9..a11a897df8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_01_07_082701) do +ActiveRecord::Schema.define(version: 2020_11_03_150431) do create_table "account_contacts", force: :cascade do |t| t.integer "account_id" @@ -241,6 +241,13 @@ t.index ["user_id"], name: "index_groups_users_on_user_id" end + create_table "imported_files", force: :cascade do |t| + t.string "filename", limit: 64, default: "", null: false + t.string "md5sum", limit: 32, default: "", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "leads", force: :cascade do |t| t.integer "user_id" t.integer "campaign_id" diff --git a/spec/factories/imported_files.rb b/spec/factories/imported_files.rb new file mode 100644 index 0000000000..0bacfbf1df --- /dev/null +++ b/spec/factories/imported_files.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :imported_file do + filename { "MyString" } + md5sum { "MyString" } + end +end diff --git a/spec/models/files/imported_file_spec.rb b/spec/models/files/imported_file_spec.rb new file mode 100644 index 0000000000..986670771d --- /dev/null +++ b/spec/models/files/imported_file_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ +# == Schema Information +# +# Table name: imported_files +# +# id :integer not null, primary key +# filename :string(64) default(""), not null +# md5sum :string(32) default(""), not null +# + +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') + +RSpec.describe ImportedFile, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 9804bbb62a7e078df4c1bfd5f13c38982a4c8ceb Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Thu, 5 Nov 2020 09:24:20 +0000 Subject: [PATCH 03/22] Fix magic string on imported file factory --- spec/factories/imported_files.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/factories/imported_files.rb b/spec/factories/imported_files.rb index 0bacfbf1df..aea1e9c6d3 100644 --- a/spec/factories/imported_files.rb +++ b/spec/factories/imported_files.rb @@ -1,3 +1,10 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ FactoryBot.define do factory :imported_file do filename { "MyString" } From 06f29f09e31f48e19f544fd506015937076199a1 Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Sat, 7 Nov 2020 16:30:14 +0000 Subject: [PATCH 04/22] Change file to be imported to MS-Excel format Spreadsheet gem only supports MS-Excel as per described: https://github.com/zdavatz/spreadsheet#description --- Gemfile | 1 + Gemfile.lock | 4 ++++ app/models/files/imported_file.rb | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 99a6106d07..457c5f2b4d 100644 --- a/Gemfile +++ b/Gemfile @@ -100,3 +100,4 @@ gem "devise-encryptable" gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby] gem 'activejob', '~> 5.2.0' gem 'ransack_ui', path: 'vendor/gems/ransack_ui-1.3.4' # Vendored until our fix is merged and released +gem 'spreadsheet' diff --git a/Gemfile.lock b/Gemfile.lock index e22d3ee844..694ee4e76d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -334,6 +334,7 @@ GEM rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 1.7) + ruby-ole (1.2.12.2) ruby-progressbar (1.10.1) rubyzip (2.3.0) sass (3.7.4) @@ -359,6 +360,8 @@ GEM sixarm_ruby_unaccent (1.2.0) sort_alphabetical (1.1.0) unicode_utils (>= 1.2.2) + spreadsheet (1.2.6) + ruby-ole (>= 1.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -470,6 +473,7 @@ DEPENDENCIES select2-rails selenium-webdriver simple_form + spreadsheet sprockets-rails (>= 3.0.0) sqlite3 (~> 1.3.13) therubyracer diff --git a/app/models/files/imported_file.rb b/app/models/files/imported_file.rb index ab2a12102d..9ac84c15ae 100644 --- a/app/models/files/imported_file.rb +++ b/app/models/files/imported_file.rb @@ -30,7 +30,7 @@ def generate_md5sum private def filetype - valid = File.open(filename).type_from_file_command == "text/xml" rescue "" + valid = File.open(filename).type_from_file_command == "application/vnd.ms-excel" rescue "" if valid == "" errors.add(:filename, "no such file") end From 11d140c7cfb8af49541e4e0d7ebb15d1e38368f6 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Thu, 17 Dec 2020 19:40:14 -0500 Subject: [PATCH 05/22] Add docker-compose.override.yml to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 39cfdaf840..bb4eec0e2f 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ Design .passenger .vagrant + +docker-compose.override.yml + From 02d3d2b3fdae45c84f076cb936a871a18883da81 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sat, 19 Dec 2020 07:39:21 -0500 Subject: [PATCH 06/22] Import campaign firts version --- .gitignore | 4 +- Gemfile | 4 + Gemfile.lock | 13 +++- .../entities/campaigns_controller.rb | 39 ++++++++++ app/models/entities/campaign.rb | 20 +++++ app/models/polymorphic/importer.rb | 30 +++++++ app/views/campaigns/_import.html.haml | 35 +++++++++ app/views/campaigns/_list_title_bar.html.haml | 14 ++++ app/views/campaigns/import.js.haml | 6 ++ app/views/campaigns/import_upload.js.haml | 5 ++ app/views/campaigns/index.html.haml | 5 +- config/initializers/paperclip.rb | 7 ++ config/routes.rb | 3 + db/migrate/20201217030615_create_importers.rb | 18 +++++ db/schema.rb | 73 +++++++++++------- lib/fat_free_crm.rb | 1 + lib/fat_free_crm/import_handle.rb | 40 ++++++++++ lib/tasks/ffcrm/import.rake | 63 +++++++++++++++ .../images/calendar_date_select/calendar.gif | Bin vendor/assets/images/chosen-sprite.png | Bin .../jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png | Bin .../jquery-ui/ui-bg_flat_0_eeeeee_40x100.png | Bin .../ui-bg_flat_100_ffffff_40x100.png | Bin .../jquery-ui/ui-bg_flat_25_3875d7_40x100.png | Bin .../jquery-ui/ui-bg_flat_55_ffffff_40x100.png | Bin .../jquery-ui/ui-bg_flat_65_3875d7_40x100.png | Bin .../jquery-ui/ui-bg_flat_75_ffffff_40x100.png | Bin .../ui-bg_highlight-soft_50_dddddd_1x100.png | Bin .../jquery-ui/ui-icons_0073ea_256x240.png | Bin .../jquery-ui/ui-icons_466bb1_256x240.png | Bin .../jquery-ui/ui-icons_ff0084_256x240.png | Bin vendor/assets/javascripts/jquery.disable.js | 0 .../javascripts/jquery_timeago/index.js | 0 .../jquery_timeago/jquery.timeago.cz.js | 0 .../jquery_timeago/jquery.timeago.de.js | 0 .../jquery_timeago/jquery.timeago.en-GB.js | 0 .../jquery_timeago/jquery.timeago.en-US.js | 0 .../jquery_timeago/jquery.timeago.es-CL.js | 0 .../jquery_timeago/jquery.timeago.es.js | 0 .../jquery_timeago/jquery.timeago.fr-CA.js | 0 .../jquery_timeago/jquery.timeago.fr.js | 0 .../jquery_timeago/jquery.timeago.it.js | 0 .../jquery_timeago/jquery.timeago.ja.js | 0 .../jquery_timeago/jquery.timeago.js | 0 .../jquery_timeago/jquery.timeago.nl.js | 0 .../jquery_timeago/jquery.timeago.pl.js | 0 .../jquery_timeago/jquery.timeago.pt-BR.js | 0 .../jquery_timeago/jquery.timeago.ru.js | 0 .../jquery_timeago/jquery.timeago.sv-SE.js | 0 .../jquery_timeago/jquery.timeago.th.js | 0 .../jquery_timeago/jquery.timeago.zh-CN.js | 0 .../jquery-ui-timepicker-addon.js | 0 .../jquery-ui-timepicker-af.js | 0 .../jquery-ui-timepicker-ca.js | 0 .../jquery-ui-timepicker-cz.js | 0 .../jquery-ui-timepicker-de.js | 0 .../jquery-ui-timepicker-el.js | 0 .../jquery-ui-timepicker-es-CL.js | 0 .../jquery-ui-timepicker-es.js | 0 .../jquery-ui-timepicker-et.js | 0 .../jquery-ui-timepicker-fi.js | 0 .../jquery-ui-timepicker-fr-CA.js | 0 .../jquery-ui-timepicker-fr.js | 0 .../jquery-ui-timepicker-gl.js | 0 .../jquery-ui-timepicker-he.js | 0 .../jquery-ui-timepicker-hu.js | 0 .../jquery-ui-timepicker-id.js | 0 .../jquery-ui-timepicker-it.js | 0 .../jquery-ui-timepicker-ja.js | 0 .../jquery-ui-timepicker-ko.js | 0 .../jquery-ui-timepicker-lt.js | 0 .../jquery-ui-timepicker-nl.js | 0 .../jquery-ui-timepicker-no.js | 0 .../jquery-ui-timepicker-pl.js | 0 .../jquery-ui-timepicker-pt-BR.js | 0 .../jquery-ui-timepicker-pt.js | 0 .../jquery-ui-timepicker-ro.js | 0 .../jquery-ui-timepicker-ru.js | 0 .../jquery-ui-timepicker-sk.js | 0 .../jquery-ui-timepicker-sv-SE.js | 0 .../jquery-ui-timepicker-th.js | 0 .../jquery-ui-timepicker-tr.js | 0 .../jquery-ui-timepicker-vi.js | 0 .../jquery-ui-timepicker-zh-CN.js | 0 .../jquery-ui-timepicker-zh-TW.js | 0 .../jquery.ui.datepicker-cz.js | 0 .../jquery.ui.datepicker-de.js | 0 .../jquery.ui.datepicker-en-GB.js | 0 .../jquery.ui.datepicker-es-CL.js | 0 .../jquery.ui.datepicker-es.js | 0 .../jquery.ui.datepicker-fr-CA.js | 0 .../jquery.ui.datepicker-fr.js | 0 .../jquery.ui.datepicker-it.js | 0 .../jquery.ui.datepicker-ja.js | 0 .../jquery.ui.datepicker-nl.js | 0 .../jquery.ui.datepicker-pl.js | 0 .../jquery.ui.datepicker-pt-BR.js | 0 .../jquery.ui.datepicker-pt.js | 0 .../jquery.ui.datepicker-ru.js | 0 .../jquery.ui.datepicker-sv-SE.js | 0 .../jquery.ui.datepicker-th.js | 0 .../jquery.ui.datepicker-zh-CN.js | 0 .../javascripts/lib/select-parser.coffee | 0 vendor/assets/javascripts/rating.js | 0 .../javascripts/textarea_autocomplete.js | 0 .../assets/stylesheets/jquery-ui.custom.scss | 0 vendor/assets/stylesheets/modalbox.css | 0 vendor/gems/globby-0.1.2/LICENSE.txt | 0 vendor/gems/globby-0.1.2/README.md | 0 vendor/gems/globby-0.1.2/Rakefile | 0 vendor/gems/globby-0.1.2/lib/globby.rb | 0 vendor/gems/globby-0.1.2/lib/globby/glob.rb | 0 .../gems/globby-0.1.2/lib/globby/globject.rb | 0 vendor/gems/globby-0.1.2/lib/globby/result.rb | 0 .../gems/globby-0.1.2/spec/gitignore_spec.rb | 0 vendor/gems/globby-0.1.2/spec/globby_spec.rb | 0 vendor/gems/ransack_ui-1.3.4/.gitignore | 0 vendor/gems/ransack_ui-1.3.4/Gemfile | 0 vendor/gems/ransack_ui-1.3.4/LICENSE.txt | 0 vendor/gems/ransack_ui-1.3.4/README.md | 0 vendor/gems/ransack_ui-1.3.4/Rakefile | 0 .../app/assets/images/ransack_ui/calendar.png | Bin .../app/assets/images/ransack_ui/delete.png | Bin .../javascripts/ransack/predicates.js.coffee | 0 .../button_group_select.js.coffee | 0 .../ransack_ui_bootstrap/index.js.coffee | 0 .../javascripts/ransack_ui_jquery/index.js | 0 .../search_form.js.coffee.erb | 0 .../ransack_ui_bootstrap/index.css | 0 .../ransack_ui_bootstrap/search.css.scss | 0 .../views/ransack_ui/_sort_fields.html.erb | 0 .../ransack_ui-1.3.4/config/locales/en.yml | 0 .../gems/ransack_ui-1.3.4/lib/ransack_ui.rb | 0 .../lib/ransack_ui/adapters/active_record.rb | 0 .../ransack_ui/adapters/active_record/base.rb | 0 .../lib/ransack_ui/controller_helpers.rb | 0 .../lib/ransack_ui/rails/engine.rb | 0 .../adapters/active_record/base.rb | 0 .../ransack_overrides/configuration.rb | 0 .../ransack_ui/ransack_overrides/context.rb | 0 .../ransack_overrides/helpers/form_builder.rb | 0 .../ransack_overrides/nodes/attribute.rb | 0 .../ransack_overrides/nodes/condition.rb | 0 .../ransack_overrides/nodes/grouping.rb | 0 .../lib/ransack_ui/version.rb | 0 .../lib/ransack_ui/view_helpers.rb | 0 .../gems/ransack_ui-1.3.4/ransack_ui.gemspec | 0 147 files changed, 347 insertions(+), 33 deletions(-) create mode 100644 app/models/polymorphic/importer.rb create mode 100644 app/views/campaigns/_import.html.haml create mode 100644 app/views/campaigns/_list_title_bar.html.haml create mode 100644 app/views/campaigns/import.js.haml create mode 100644 app/views/campaigns/import_upload.js.haml create mode 100644 config/initializers/paperclip.rb create mode 100644 db/migrate/20201217030615_create_importers.rb create mode 100644 lib/fat_free_crm/import_handle.rb create mode 100644 lib/tasks/ffcrm/import.rake mode change 100644 => 100755 vendor/assets/images/calendar_date_select/calendar.gif mode change 100644 => 100755 vendor/assets/images/chosen-sprite.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_flat_100_ffffff_40x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_flat_25_3875d7_40x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_flat_65_3875d7_40x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-icons_0073ea_256x240.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-icons_466bb1_256x240.png mode change 100644 => 100755 vendor/assets/images/jquery-ui/ui-icons_ff0084_256x240.png mode change 100644 => 100755 vendor/assets/javascripts/jquery.disable.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/index.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.es-CL.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.nl.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-addon.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-af.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ca.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-cz.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-de.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-el.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es-CL.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-et.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fi.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr-CA.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-gl.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-he.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-hu.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-id.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-it.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ja.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ko.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-lt.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-nl.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-no.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pl.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt-BR.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ro.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ru.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sk.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sv-SE.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-th.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-tr.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-vi.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-CN.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-TW.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-cz.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-de.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-en-GB.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es-CL.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr-CA.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-it.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ja.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-nl.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pl.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt-BR.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ru.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-sv-SE.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-th.js mode change 100644 => 100755 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-zh-CN.js mode change 100644 => 100755 vendor/assets/javascripts/lib/select-parser.coffee mode change 100644 => 100755 vendor/assets/javascripts/rating.js mode change 100644 => 100755 vendor/assets/javascripts/textarea_autocomplete.js mode change 100644 => 100755 vendor/assets/stylesheets/jquery-ui.custom.scss mode change 100644 => 100755 vendor/assets/stylesheets/modalbox.css mode change 100644 => 100755 vendor/gems/globby-0.1.2/LICENSE.txt mode change 100644 => 100755 vendor/gems/globby-0.1.2/README.md mode change 100644 => 100755 vendor/gems/globby-0.1.2/Rakefile mode change 100644 => 100755 vendor/gems/globby-0.1.2/lib/globby.rb mode change 100644 => 100755 vendor/gems/globby-0.1.2/lib/globby/glob.rb mode change 100644 => 100755 vendor/gems/globby-0.1.2/lib/globby/globject.rb mode change 100644 => 100755 vendor/gems/globby-0.1.2/lib/globby/result.rb mode change 100644 => 100755 vendor/gems/globby-0.1.2/spec/gitignore_spec.rb mode change 100644 => 100755 vendor/gems/globby-0.1.2/spec/globby_spec.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/.gitignore mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/Gemfile mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/LICENSE.txt mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/README.md mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/Rakefile mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/calendar.png mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/delete.png mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack/predicates.js.coffee mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/button_group_select.js.coffee mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/index.js.coffee mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/index.js mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/search_form.js.coffee.erb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/index.css mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/search.css.scss mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/app/views/ransack_ui/_sort_fields.html.erb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/config/locales/en.yml mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record/base.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/controller_helpers.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/rails/engine.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/adapters/active_record/base.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/configuration.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/context.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/helpers/form_builder.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/attribute.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/condition.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/grouping.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/version.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/view_helpers.rb mode change 100644 => 100755 vendor/gems/ransack_ui-1.3.4/ransack_ui.gemspec diff --git a/.gitignore b/.gitignore index bb4eec0e2f..422fa5e2ca 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ Gemfile.ci.lock public/avatars/**/* public/assets +public/importers/ tmp Design @@ -39,4 +40,5 @@ Design .vagrant docker-compose.override.yml - +.bash_history +.local/ diff --git a/Gemfile b/Gemfile index 457c5f2b4d..d2e4040e13 100644 --- a/Gemfile +++ b/Gemfile @@ -101,3 +101,7 @@ gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby] gem 'activejob', '~> 5.2.0' gem 'ransack_ui', path: 'vendor/gems/ransack_ui-1.3.4' # Vendored until our fix is merged and released gem 'spreadsheet' + +gem "roo", "~> 2.8" + +gem "roo-xls", "~> 1.2" diff --git a/Gemfile.lock b/Gemfile.lock index 694ee4e76d..c71acde36c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -176,6 +176,7 @@ GEM jquery-ui-rails (6.0.1) railties (>= 3.2.16) libv8 (3.16.14.19) + libv8 (3.16.14.19-x86_64-linux) listen (3.2.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -302,6 +303,13 @@ GEM railties (>= 4.2.0, < 6.0) responds_to_parent (2.0.0) actionpack (>= 3.2.22, < 6.0) + roo (2.8.3) + nokogiri (~> 1) + rubyzip (>= 1.3.0, < 3.0.0) + roo-xls (1.2.0) + nokogiri + roo (>= 2.0.0, < 3) + spreadsheet (> 0.9.0) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) @@ -406,6 +414,7 @@ GEM PLATFORMS ruby + x86_64-linux DEPENDENCIES activejob (~> 5.2.0) @@ -465,6 +474,8 @@ DEPENDENCIES rb-inotify responders (~> 2.0) responds_to_parent + roo (~> 2.8) + roo-xls (~> 1.2) rspec-activemodel-mocks rspec-rails rubocop (~> 0.76.0) @@ -486,4 +497,4 @@ DEPENDENCIES zeus BUNDLED WITH - 2.1.4 + 2.2.2 diff --git a/app/controllers/entities/campaigns_controller.rb b/app/controllers/entities/campaigns_controller.rb index b09cd138af..9a9c76334c 100644 --- a/app/controllers/entities/campaigns_controller.rb +++ b/app/controllers/entities/campaigns_controller.rb @@ -5,6 +5,7 @@ # Fat Free CRM is freely distributable under the terms of MIT license. # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php #------------------------------------------------------------------------------ + class CampaignsController < EntitiesController before_action :get_data_for_sidebar, only: :index @@ -160,6 +161,37 @@ def filter end end + # get /campaigns/import AJAX + #---------------------------------------------------------------------------- + def import + @importer = Importer.new + respond_with(@importer) + end + + # patch /campaigns/import AJAX + #---------------------------------------------------------------------------- + def import_upload + @error = false + @result = { + items: [], + errors: [] + } + + if params[:importer] + @importer = Importer.create(import_params) + @importer.entity_type = 'campaign' + if @importer.valid? + @importer.save + @result = FatFreeCRM::ImportHandle.process(@importer) + else + puts @importer.errors.full_messages + @result[:errors].push(@importer.errors.full_messages) + @error = true + end + end + respond_with(@error,@result) + end + private #---------------------------------------------------------------------------- @@ -204,4 +236,11 @@ def get_data_for_sidebar end @campaign_status_total[:other] += @campaign_status_total[:all] end + + def import_params + return {} unless params[:importer] + + params[:importer] + .permit(:attachment) + end end diff --git a/app/models/entities/campaign.rb b/app/models/entities/campaign.rb index 460a29c238..96c959f912 100644 --- a/app/models/entities/campaign.rb +++ b/app/models/entities/campaign.rb @@ -98,6 +98,26 @@ def discard!(attachment) end end + # Save Campaign from row in xls + def self.import_from_xls(row,headers) + campaign = Campaign.new + campaign.name = row[headers['Name']] + campaign.access = row[headers['Access']] + campaign.status = row[headers['Status']] + campaign.budget =row[headers['Budget']] + campaign.target_leads =row[headers['target leads']] + campaign.target_conversion =row[headers['Target conversion']] + campaign.leads_count =row[headers['Number of leads']] + campaign.opportunities_count =row[headers['Total Opportunities']] + campaign.revenue =row[headers['target revenue']] + campaign.starts_on =row[headers['start date']] + campaign.ends_on =row[headers['end date']] + campaign.objectives =row[headers['Objectives']] + campaign.background_info =row[headers['Background']] + campaign.save + campaign + end + private # Make sure end date > start date. diff --git a/app/models/polymorphic/importer.rb b/app/models/polymorphic/importer.rb new file mode 100644 index 0000000000..579dd0483f --- /dev/null +++ b/app/models/polymorphic/importer.rb @@ -0,0 +1,30 @@ +# == Schema Information +# +# Table name: importers +# +# id :integer not null, primary key +# entity_type :string +# attachment_file_size :integer +# attachment_file_name :string(255) +# attachment_content_type :string(255) +# status :string(255) +# created_at :datetime +# updated_at :datetime +# + +class Importer < ActiveRecord::Base + attr_accessor :status, :entity_type + + has_attached_file :attachment, :path => ":rails_root/public/importers/:id/:filename" + + # validates_attachment :attachment, presence: true, + # content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'] } + + validates_attachment_content_type :attachment, + :content_type => %w(text/xml application/xml application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/x-ole-storage), + :message => 'Only EXCEL files are allowed.' + validates_attachment_file_name :attachment, matches: [/\.xls/, /\.xlsx?$/] + + + ActiveSupport.run_load_hooks(:fat_free_crm_importer, self) +end diff --git a/app/views/campaigns/_import.html.haml b/app/views/campaigns/_import.html.haml new file mode 100644 index 0000000000..8689ca2ea2 --- /dev/null +++ b/app/views/campaigns/_import.html.haml @@ -0,0 +1,35 @@ += form_for(@importer, url: import_upload_campaign_path(format: "js"), method: "patch", html: { multipart: true, target: "uploading", onsubmit: "$('#import_submit').disabled = true"}) do |f| + = link_to_close new_campaign_path + -# todo + -#= error_messages_for :avatar, object: @user.avatar, object_name: t('avatar') + %p + %small 'Descripcion aqui' + + %div 'File': + = fields_for(Importer) do |a| + %div= a.file_field :attachment + + .buttonbar + = f.submit t(:upload_picture), id: "import_submit" + #{t :or} + = link_to_cancel new_campaign_path + +-#= simple_form_for(@campaign, html: one_submit_only, remote: true) do |f| +-# = link_to_close new_campaign_path +-# = f.hidden_field :user_id +-# +-# = f.error_messages object_name: t('campaign') +-# +-# .section +-# %table +-# %tr +-# %td(colspan="5") +-# .label.top.req 'File': +-# = f.file_field :file, autofocus: true, style: "width:500px" +-# +-# = hook(:entity_form, self, {f: f, entity: @campaign}) +-# +-# .buttonbar +-# = f.submit 'Import campaign' +-# #{t :or} +-# = link_to_cancel new_campaign_path \ No newline at end of file diff --git a/app/views/campaigns/_list_title_bar.html.haml b/app/views/campaigns/_list_title_bar.html.haml new file mode 100644 index 0000000000..04860525d9 --- /dev/null +++ b/app/views/campaigns/_list_title_bar.html.haml @@ -0,0 +1,14 @@ +- model_name = controller_name.singularize +- model_klass = model_name.camelcase.constantize + +.title_tools + #buttons + = view_buttons + .create_asset + = link_to_inline("create_#{model_name}".to_sym, send("new_#{model_name}_path"), text: t("create_#{model_name}".to_sym)) + .import_asset + = link_to_inline("import_#{model_name}".to_sym, send("import_#{model_name}_path"), text: t("import_#{model_name}".to_sym)) + +.title + %span{id: "create_#{model_name}_title"} #{t controller_name.to_sym} + = image_tag("loading.gif", size: :thumb, id: "loading", style: "display: none;") diff --git a/app/views/campaigns/import.js.haml b/app/views/campaigns/import.js.haml new file mode 100644 index 0000000000..b380bc4ab6 --- /dev/null +++ b/app/views/campaigns/import.js.haml @@ -0,0 +1,6 @@ +- import_id = "campaign_import" + +crm.flick('empty', 'toggle'); +crm.flip_form('#{import_id}'); +$('##{import_id}').html('#{ j render(partial: "import") }'); +crm.set_title('#{import_id}', '#{ j t(import_id) }'); diff --git a/app/views/campaigns/import_upload.js.haml b/app/views/campaigns/import_upload.js.haml new file mode 100644 index 0000000000..705a07dadb --- /dev/null +++ b/app/views/campaigns/import_upload.js.haml @@ -0,0 +1,5 @@ +- if not @error + $('#campaign_import').html('#{ j render(partial: "import") }'); +- else + $('#campaign_import').html('#{ j render(partial: "import") }'); + $('#campaign_import').effect("shake", { duration:250, distance: 6 }); diff --git a/app/views/campaigns/index.html.haml b/app/views/campaigns/index.html.haml index 9f1c71384a..533b43f27d 100644 --- a/app/views/campaigns/index.html.haml +++ b/app/views/campaigns/index.html.haml @@ -1,8 +1,11 @@ = styles_for :campaign -= render 'entities/title_bar' += render 'list_title_bar' .remote#create_campaign{ hidden } +.remote#campaign_import{ hidden } + +%iframe#uploading{ name: "uploading", style: "width:100px; height:10px; border:5px" } = render 'search' diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb new file mode 100644 index 0000000000..b85e39ae1a --- /dev/null +++ b/config/initializers/paperclip.rb @@ -0,0 +1,7 @@ +module Paperclip + class MediaTypeSpoofDetector + def spoofed? + false + end + end +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1efaac95b3..37f8485217 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -209,4 +209,7 @@ resources :settings, only: :index resources :plugins, only: :index end + + get 'campaigns/import',to: 'campaigns#import', as: :import_campaign + match 'campaigns/import-upload',to: 'campaigns#import_upload', as: :import_upload_campaign, via: %i[put patch] end diff --git a/db/migrate/20201217030615_create_importers.rb b/db/migrate/20201217030615_create_importers.rb new file mode 100644 index 0000000000..c9630dfbea --- /dev/null +++ b/db/migrate/20201217030615_create_importers.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class CreateImporters < ActiveRecord::Migration[4.2] + def self.up + create_table :importers do |t| + t.integer :attachment_file_size # Uploaded file size + t.string :attachment_file_name # Uploaded full file name + t.string :attachment_content_type # MIME content type + t.string :entity_type # led, campaign + t.string :status # new, success, error + t.timestamps + end + end + + def self.down + drop_table :importers + end +end diff --git a/db/schema.rb b/db/schema.rb index a11a897df8..d73e59de48 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_11_03_150431) do +ActiveRecord::Schema.define(version: 2020_12_17_030615) do - create_table "account_contacts", force: :cascade do |t| + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "account_contacts", id: :serial, force: :cascade do |t| t.integer "account_id" t.integer "contact_id" t.datetime "deleted_at" @@ -21,7 +24,7 @@ t.index ["account_id", "contact_id"], name: "index_account_contacts_on_account_id_and_contact_id" end - create_table "account_opportunities", force: :cascade do |t| + create_table "account_opportunities", id: :serial, force: :cascade do |t| t.integer "account_id" t.integer "opportunity_id" t.datetime "deleted_at" @@ -30,7 +33,7 @@ t.index ["account_id", "opportunity_id"], name: "index_account_opportunities_on_account_id_and_opportunity_id" end - create_table "accounts", force: :cascade do |t| + create_table "accounts", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "assigned_to" t.string "name", limit: 64, default: "", null: false @@ -53,7 +56,7 @@ t.index ["user_id", "name", "deleted_at"], name: "index_accounts_on_user_id_and_name_and_deleted_at", unique: true end - create_table "activities", force: :cascade do |t| + create_table "activities", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "subject_type" t.integer "subject_id" @@ -66,7 +69,7 @@ t.index ["user_id"], name: "index_activities_on_user_id" end - create_table "addresses", force: :cascade do |t| + create_table "addresses", id: :serial, force: :cascade do |t| t.string "street1" t.string "street2" t.string "city", limit: 64 @@ -83,7 +86,7 @@ t.index ["addressable_id", "addressable_type"], name: "index_addresses_on_addressable_id_and_addressable_type" end - create_table "avatars", force: :cascade do |t| + create_table "avatars", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "entity_type" t.integer "entity_id" @@ -94,7 +97,7 @@ t.datetime "updated_at" end - create_table "campaigns", force: :cascade do |t| + create_table "campaigns", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "assigned_to" t.string "name", limit: 64, default: "", null: false @@ -119,7 +122,7 @@ t.index ["user_id", "name", "deleted_at"], name: "index_campaigns_on_user_id_and_name_and_deleted_at", unique: true end - create_table "comments", force: :cascade do |t| + create_table "comments", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "commentable_type" t.integer "commentable_id" @@ -131,7 +134,7 @@ t.string "state", limit: 16, default: "Expanded", null: false end - create_table "contact_opportunities", force: :cascade do |t| + create_table "contact_opportunities", id: :serial, force: :cascade do |t| t.integer "contact_id" t.integer "opportunity_id" t.string "role", limit: 32 @@ -141,7 +144,7 @@ t.index ["contact_id", "opportunity_id"], name: "index_contact_opportunities_on_contact_id_and_opportunity_id" end - create_table "contacts", force: :cascade do |t| + create_table "contacts", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "lead_id" t.integer "assigned_to" @@ -173,7 +176,7 @@ t.index ["user_id", "last_name", "deleted_at"], name: "id_last_name_deleted", unique: true end - create_table "emails", force: :cascade do |t| + create_table "emails", id: :serial, force: :cascade do |t| t.string "imap_message_id", null: false t.integer "user_id" t.string "mediator_type" @@ -194,7 +197,7 @@ t.index ["mediator_id", "mediator_type"], name: "index_emails_on_mediator_id_and_mediator_type" end - create_table "field_groups", force: :cascade do |t| + create_table "field_groups", id: :serial, force: :cascade do |t| t.string "name", limit: 64 t.string "label", limit: 128 t.integer "position" @@ -205,7 +208,7 @@ t.string "klass_name", limit: 32 end - create_table "fields", force: :cascade do |t| + create_table "fields", id: :serial, force: :cascade do |t| t.string "type" t.integer "field_group_id" t.integer "position" @@ -217,17 +220,17 @@ t.text "collection" t.boolean "disabled" t.boolean "required" - t.integer "maxlength", limit: 4 + t.integer "maxlength" t.datetime "created_at" t.datetime "updated_at" t.integer "pair_id" t.text "settings" - t.integer "minlength", limit: 4, default: 0 + t.integer "minlength", default: 0 t.index ["field_group_id"], name: "index_fields_on_field_group_id" t.index ["name"], name: "index_fields_on_name" end - create_table "groups", force: :cascade do |t| + create_table "groups", id: :serial, force: :cascade do |t| t.string "name" t.datetime "created_at" t.datetime "updated_at" @@ -241,14 +244,24 @@ t.index ["user_id"], name: "index_groups_users_on_user_id" end - create_table "imported_files", force: :cascade do |t| + create_table "imported_files", id: :serial, force: :cascade do |t| t.string "filename", limit: 64, default: "", null: false t.string "md5sum", limit: 32, default: "", null: false t.datetime "created_at" t.datetime "updated_at" end - create_table "leads", force: :cascade do |t| + create_table "importers", id: :serial, force: :cascade do |t| + t.integer "attachment_file_size" + t.string "attachment_file_name" + t.string "attachment_content_type" + t.string "entity_type" + t.string "status" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "leads", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "campaign_id" t.integer "assigned_to" @@ -280,7 +293,7 @@ t.index ["user_id", "last_name", "deleted_at"], name: "index_leads_on_user_id_and_last_name_and_deleted_at", unique: true end - create_table "lists", force: :cascade do |t| + create_table "lists", id: :serial, force: :cascade do |t| t.string "name" t.text "url" t.datetime "created_at" @@ -289,7 +302,7 @@ t.index ["user_id"], name: "index_lists_on_user_id" end - create_table "opportunities", force: :cascade do |t| + create_table "opportunities", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "campaign_id" t.integer "assigned_to" @@ -310,7 +323,7 @@ t.index ["user_id", "name", "deleted_at"], name: "id_name_deleted", unique: true end - create_table "permissions", force: :cascade do |t| + create_table "permissions", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "asset_type" t.integer "asset_id" @@ -322,7 +335,7 @@ t.index ["user_id"], name: "index_permissions_on_user_id" end - create_table "preferences", force: :cascade do |t| + create_table "preferences", id: :serial, force: :cascade do |t| t.integer "user_id" t.string "name", limit: 32, default: "", null: false t.text "value" @@ -331,7 +344,7 @@ t.index ["user_id", "name"], name: "index_preferences_on_user_id_and_name" end - create_table "sessions", force: :cascade do |t| + create_table "sessions", id: :serial, force: :cascade do |t| t.string "session_id", null: false t.text "data" t.datetime "created_at" @@ -340,7 +353,7 @@ t.index ["updated_at"], name: "index_sessions_on_updated_at" end - create_table "settings", force: :cascade do |t| + create_table "settings", id: :serial, force: :cascade do |t| t.string "name", limit: 32, default: "", null: false t.text "value" t.datetime "created_at" @@ -348,7 +361,7 @@ t.index ["name"], name: "index_settings_on_name" end - create_table "taggings", force: :cascade do |t| + create_table "taggings", id: :serial, force: :cascade do |t| t.integer "tag_id" t.integer "taggable_id" t.integer "tagger_id" @@ -360,13 +373,13 @@ t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context" end - create_table "tags", force: :cascade do |t| + create_table "tags", id: :serial, force: :cascade do |t| t.string "name" t.integer "taggings_count", default: 0 t.index ["name"], name: "index_tags_on_name", unique: true end - create_table "tasks", force: :cascade do |t| + create_table "tasks", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "assigned_to" t.integer "completed_by" @@ -387,7 +400,7 @@ t.index ["user_id", "name", "deleted_at"], name: "index_tasks_on_user_id_and_name_and_deleted_at", unique: true end - create_table "users", force: :cascade do |t| + create_table "users", id: :serial, force: :cascade do |t| t.string "username", limit: 32, default: "", null: false t.string "email", limit: 254, default: "", null: false t.string "first_name", limit: 32 @@ -430,7 +443,7 @@ t.index ["username", "deleted_at"], name: "index_users_on_username_and_deleted_at", unique: true end - create_table "versions", force: :cascade do |t| + create_table "versions", id: :serial, force: :cascade do |t| t.string "item_type", null: false t.integer "item_id", null: false t.string "event", limit: 512, null: false diff --git a/lib/fat_free_crm.rb b/lib/fat_free_crm.rb index 741b011274..0e74ebe027 100644 --- a/lib/fat_free_crm.rb +++ b/lib/fat_free_crm.rb @@ -52,6 +52,7 @@ def application? require "fat_free_crm/tabs" require "fat_free_crm/callback" require "fat_free_crm/view_factory" +require "fat_free_crm/import_handle" require "activemodel-serializers-xml" require "country_select" diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb new file mode 100644 index 0000000000..8ab68bf24a --- /dev/null +++ b/lib/fat_free_crm/import_handle.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ +require 'roo' + +module FatFreeCRM + class ImportHandle + class << self + def process(importer) + result = { + items: [], + errors: [] + } + xlsx = Roo::Spreadsheet.open(importer.attachment.path) + + xlsx.each_with_pagename do |name, sheet| + headers = Hash.new + sheet.row(1).each_with_index { |header, i| + headers[header] = i + } + ((sheet.first_row + 1)..sheet.last_row).each do |row| + campaign = Campaign.import_from_xls(sheet.row(row), headers) + result[:items].push(campaign) + if campaign.errors.count + result[:errors].push(campaign.errors.full_messages) + end + end + end + + result + end + end + end +end + + diff --git a/lib/tasks/ffcrm/import.rake b/lib/tasks/ffcrm/import.rake new file mode 100644 index 0000000000..3681cf3e2b --- /dev/null +++ b/lib/tasks/ffcrm/import.rake @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ +namespace :ffcrm do + namespace :import do + desc "Import files..." + task process: :environment do + require 'roo' + + importers = Importer.all + importers.each do |importer| + require 'roo' + + xlsx = Roo::Spreadsheet.open(importer.attachment.path, extension: :xls) + + xlsx.each_with_pagename do |name, sheet| + headers = Hash.new + sheet.row(1).each_with_index {|header,i| + headers[header] = i + } + + ((sheet.first_row + 1)..sheet.last_row).each do |row| + campaign = Campaign.new + campaign.name = sheet.row(row)[headers['Name']] + campaign.access = sheet.row(row)[headers['Access']] + campaign.status = sheet.row(row)[headers['Status']] + campaign.budget =sheet.row(row)[headers['Budget']] + campaign.target_leads =sheet.row(row)[headers['target leads']] + campaign.target_conversion =sheet.row(row)[headers['Target conversion']] + campaign.leads_count =sheet.row(row)[headers['Number of leads']] + campaign.opportunities_count =sheet.row(row)[headers['Total Opportunities']] + campaign.revenue =sheet.row(row)[headers['target revenue']] + campaign.starts_on =sheet.row(row)[headers['start date']] + campaign.ends_on =sheet.row(row)[headers['end date']] + campaign.objectives =sheet.row(row)[headers['Objectives']] + campaign.background_info =sheet.row(row)[headers['Background']] + if campaign.save + puts 'Saved' + else + puts campaign.errors.full_messages + end + + + # headers.each do |header, i | + # value = sheet.row(row)[i] + # end + end + + # sheet.each_row(offset: 1) do |row| # skip first row + # puts row + # end + end + + + puts + end + end + end +end diff --git a/vendor/assets/images/calendar_date_select/calendar.gif b/vendor/assets/images/calendar_date_select/calendar.gif old mode 100644 new mode 100755 diff --git a/vendor/assets/images/chosen-sprite.png b/vendor/assets/images/chosen-sprite.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_100_ffffff_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_100_ffffff_40x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_25_3875d7_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_25_3875d7_40x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_65_3875d7_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_65_3875d7_40x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png b/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-icons_0073ea_256x240.png b/vendor/assets/images/jquery-ui/ui-icons_0073ea_256x240.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-icons_466bb1_256x240.png b/vendor/assets/images/jquery-ui/ui-icons_466bb1_256x240.png old mode 100644 new mode 100755 diff --git a/vendor/assets/images/jquery-ui/ui-icons_ff0084_256x240.png b/vendor/assets/images/jquery-ui/ui-icons_ff0084_256x240.png old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery.disable.js b/vendor/assets/javascripts/jquery.disable.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/index.js b/vendor/assets/javascripts/jquery_timeago/index.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es-CL.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es-CL.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.nl.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.nl.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-addon.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-addon.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-af.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-af.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ca.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ca.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-cz.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-cz.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-de.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-de.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-el.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-el.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es-CL.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es-CL.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-et.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-et.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fi.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fi.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr-CA.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr-CA.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-gl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-gl.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-he.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-he.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-hu.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-hu.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-id.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-id.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-it.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-it.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ja.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ja.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ko.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ko.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-lt.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-lt.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-nl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-nl.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-no.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-no.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pl.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt-BR.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt-BR.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ro.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ro.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ru.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ru.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sk.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sk.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sv-SE.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sv-SE.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-th.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-th.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-tr.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-tr.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-vi.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-vi.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-CN.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-CN.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-TW.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-TW.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-cz.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-cz.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-de.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-de.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-en-GB.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-en-GB.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es-CL.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es-CL.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr-CA.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr-CA.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-it.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-it.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ja.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ja.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-nl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-nl.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pl.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt-BR.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt-BR.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ru.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ru.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-sv-SE.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-sv-SE.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-th.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-th.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-zh-CN.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-zh-CN.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/lib/select-parser.coffee b/vendor/assets/javascripts/lib/select-parser.coffee old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/rating.js b/vendor/assets/javascripts/rating.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/textarea_autocomplete.js b/vendor/assets/javascripts/textarea_autocomplete.js old mode 100644 new mode 100755 diff --git a/vendor/assets/stylesheets/jquery-ui.custom.scss b/vendor/assets/stylesheets/jquery-ui.custom.scss old mode 100644 new mode 100755 diff --git a/vendor/assets/stylesheets/modalbox.css b/vendor/assets/stylesheets/modalbox.css old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/LICENSE.txt b/vendor/gems/globby-0.1.2/LICENSE.txt old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/README.md b/vendor/gems/globby-0.1.2/README.md old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/Rakefile b/vendor/gems/globby-0.1.2/Rakefile old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/lib/globby.rb b/vendor/gems/globby-0.1.2/lib/globby.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/lib/globby/glob.rb b/vendor/gems/globby-0.1.2/lib/globby/glob.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/lib/globby/globject.rb b/vendor/gems/globby-0.1.2/lib/globby/globject.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/lib/globby/result.rb b/vendor/gems/globby-0.1.2/lib/globby/result.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/spec/gitignore_spec.rb b/vendor/gems/globby-0.1.2/spec/gitignore_spec.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/globby-0.1.2/spec/globby_spec.rb b/vendor/gems/globby-0.1.2/spec/globby_spec.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/.gitignore b/vendor/gems/ransack_ui-1.3.4/.gitignore old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/Gemfile b/vendor/gems/ransack_ui-1.3.4/Gemfile old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/LICENSE.txt b/vendor/gems/ransack_ui-1.3.4/LICENSE.txt old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/README.md b/vendor/gems/ransack_ui-1.3.4/README.md old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/Rakefile b/vendor/gems/ransack_ui-1.3.4/Rakefile old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/calendar.png b/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/calendar.png old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/delete.png b/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/delete.png old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack/predicates.js.coffee b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack/predicates.js.coffee old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/button_group_select.js.coffee b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/button_group_select.js.coffee old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/index.js.coffee b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/index.js.coffee old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/index.js b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/index.js old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/search_form.js.coffee.erb b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/search_form.js.coffee.erb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/index.css b/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/index.css old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/search.css.scss b/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/search.css.scss old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/app/views/ransack_ui/_sort_fields.html.erb b/vendor/gems/ransack_ui-1.3.4/app/views/ransack_ui/_sort_fields.html.erb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/config/locales/en.yml b/vendor/gems/ransack_ui-1.3.4/config/locales/en.yml old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record/base.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record/base.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/controller_helpers.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/controller_helpers.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/rails/engine.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/rails/engine.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/adapters/active_record/base.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/adapters/active_record/base.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/configuration.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/configuration.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/context.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/context.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/helpers/form_builder.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/helpers/form_builder.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/attribute.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/attribute.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/condition.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/condition.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/grouping.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/grouping.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/version.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/version.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/view_helpers.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/view_helpers.rb old mode 100644 new mode 100755 diff --git a/vendor/gems/ransack_ui-1.3.4/ransack_ui.gemspec b/vendor/gems/ransack_ui-1.3.4/ransack_ui.gemspec old mode 100644 new mode 100755 From a0473436c8374d0f9c86eb2bbdbf3d78ed91d496 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Mon, 21 Dec 2020 07:54:23 -0500 Subject: [PATCH 07/22] Remove extension in shema --- db/schema.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index d73e59de48..e4be7b7eab 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,10 +11,6 @@ # It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema.define(version: 2020_12_17_030615) do - - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - create_table "account_contacts", id: :serial, force: :cascade do |t| t.integer "account_id" t.integer "contact_id" From 96c366120d2e8a78e1f8510ce0d9b097066f1b2a Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sat, 26 Dec 2020 11:14:41 -0500 Subject: [PATCH 08/22] Importe new version init --- .../entities/campaigns_controller.rb | 39 ------- app/controllers/importers_controller.rb | 108 ++++++++++++++++++ app/models/entities/lead.rb | 8 ++ app/views/campaigns/_title_bar.html.haml | 4 +- app/views/campaigns/show.html.haml | 3 + .../campaigns/uploads_import_leads.js.haml | 6 + .../_import.html.haml | 5 +- app/views/importers/_import_leads.html.haml | 17 +++ .../importers/_import_leads_maps.html.haml | 1 + .../{campaigns => importers}/import.js.haml | 0 app/views/importers/import_leads.js.haml | 6 + .../import_upload.js.haml | 0 config/locales/fat_free_crm.en-US.yml | 7 ++ config/locales/fat_free_crm.es.yml | 6 + config/routes.rb | 6 +- lib/fat_free_crm/import_handle.rb | 34 +++++- 16 files changed, 202 insertions(+), 48 deletions(-) create mode 100644 app/controllers/importers_controller.rb create mode 100644 app/views/campaigns/uploads_import_leads.js.haml rename app/views/{campaigns => importers}/_import.html.haml (80%) create mode 100644 app/views/importers/_import_leads.html.haml create mode 100644 app/views/importers/_import_leads_maps.html.haml rename app/views/{campaigns => importers}/import.js.haml (100%) create mode 100644 app/views/importers/import_leads.js.haml rename app/views/{campaigns => importers}/import_upload.js.haml (100%) diff --git a/app/controllers/entities/campaigns_controller.rb b/app/controllers/entities/campaigns_controller.rb index 9a9c76334c..b09cd138af 100644 --- a/app/controllers/entities/campaigns_controller.rb +++ b/app/controllers/entities/campaigns_controller.rb @@ -5,7 +5,6 @@ # Fat Free CRM is freely distributable under the terms of MIT license. # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php #------------------------------------------------------------------------------ - class CampaignsController < EntitiesController before_action :get_data_for_sidebar, only: :index @@ -161,37 +160,6 @@ def filter end end - # get /campaigns/import AJAX - #---------------------------------------------------------------------------- - def import - @importer = Importer.new - respond_with(@importer) - end - - # patch /campaigns/import AJAX - #---------------------------------------------------------------------------- - def import_upload - @error = false - @result = { - items: [], - errors: [] - } - - if params[:importer] - @importer = Importer.create(import_params) - @importer.entity_type = 'campaign' - if @importer.valid? - @importer.save - @result = FatFreeCRM::ImportHandle.process(@importer) - else - puts @importer.errors.full_messages - @result[:errors].push(@importer.errors.full_messages) - @error = true - end - end - respond_with(@error,@result) - end - private #---------------------------------------------------------------------------- @@ -236,11 +204,4 @@ def get_data_for_sidebar end @campaign_status_total[:other] += @campaign_status_total[:all] end - - def import_params - return {} unless params[:importer] - - params[:importer] - .permit(:attachment) - end end diff --git a/app/controllers/importers_controller.rb b/app/controllers/importers_controller.rb new file mode 100644 index 0000000000..632bfb36e6 --- /dev/null +++ b/app/controllers/importers_controller.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ + +class ImportersController < ApplicationController + +=begin + # get /campaigns/import AJAX + #---------------------------------------------------------------------------- + def import + @importer = Importer.new + @importer.entity_type = 'Campaign' + respond_with(@importer) + end + + # patch /campaigns/import AJAX + #---------------------------------------------------------------------------- + def import_upload + @error = false + @result = { + items: [], + errors: [] + } + + if params[:importer] + @importer = Importer.create(import_params) + if @importer.valid? + @importer.save + @result = FatFreeCRM::ImportHandle.process(@importer) + else + puts @importer.errors.full_messages + @result[:errors].push(@importer.errors.full_messages) + @error = true + end + end + respond_with(@error,@result) + end + + + # get /campaigns/%id/import AJAX + #---------------------------------------------------------------------------- + def import_leads + @importer = Importer.new + @importer.entity_type = 'Lead' + respond_with(@importer) + end + + # patch /campaigns/import AJAX + #---------------------------------------------------------------------------- + def uploads_import_leads + @error = false + @result = { + items: [], + errors: [] + } + + if params[:importer] + @importer = Importer.create(import_params) + if @importer.valid? + @importer.save + @colummns = FatFreeCRM::ImportHandle.get_columns(@importer.attachment.path) + else + puts @importer.errors.full_messages + @result[:errors].push(@importer.errors.full_messages) + @error = true + end + end + respond_with(@colummns) do |format| + format.js { render :uploads_import_leads } + end + end + +=end + # post /importers/create + #---------------------------------------------------------------------------- +=begin + def create + @error = false + @result = { + items: [], + errors: [] + } + + if params[:importer] + @importer = Importer.create(import_params) + if @importer.valid? + @importer.save + @result = FatFreeCRM::ImportHandle.process(@importer) + else + puts @importer.errors.full_messages + @result[:errors].push(@importer.errors.full_messages) + @error = true + end + end + respond_with(@error,@result) + end +=end + + private + + def importer_params + params.require(:importer).permit(:attachment,:entity_type,:entity_id) + end +end diff --git a/app/models/entities/lead.rb b/app/models/entities/lead.rb index 680449f441..6d7074da62 100644 --- a/app/models/entities/lead.rb +++ b/app/models/entities/lead.rb @@ -165,6 +165,14 @@ def full_name(format = nil) end alias name full_name + # Save Campaign from row in xls + def self.import_from_xls(row,headers) + lead = Lead.new + lead.name = row[headers['Name']] + lead.save + lead + end + private #---------------------------------------------------------------------------- diff --git a/app/views/campaigns/_title_bar.html.haml b/app/views/campaigns/_title_bar.html.haml index 3933786f88..71c82814b3 100644 --- a/app/views/campaigns/_title_bar.html.haml +++ b/app/views/campaigns/_title_bar.html.haml @@ -1,7 +1,9 @@ #confirm{ hidden } .title_tools#menu = link_to_inline(:edit_campaign, edit_campaign_path(@campaign), text: t(:edit)) + " | " - = link_to_function(t(:delete) + '?', confirm_delete(@campaign)) + = link_to_function(t(:delete) + '?', confirm_delete(@campaign)) + " | " + = link_to_inline(:import_leads, import_leads_campaign_path(@campaign), text: t("import_leads".to_sym)) + .title_tools#buttons = view_buttons .title#edit_campaign_title diff --git a/app/views/campaigns/show.html.haml b/app/views/campaigns/show.html.haml index 10f3396cd7..7f56d7de46 100755 --- a/app/views/campaigns/show.html.haml +++ b/app/views/campaigns/show.html.haml @@ -9,6 +9,9 @@ = render 'campaigns/title_bar', campaign: @campaign = render "comments/new", commentable: @campaign + .remote#campaign_import_leads{ hidden } + %iframe#uploading{ name: "uploading", style: "width:100px; height:10px; border:5px" } + = render partial: "shared/timeline", collection: @timeline = hook(:show_campaign_bottom, self, {entity: @campaign}) do diff --git a/app/views/campaigns/uploads_import_leads.js.haml b/app/views/campaigns/uploads_import_leads.js.haml new file mode 100644 index 0000000000..ce24a34d64 --- /dev/null +++ b/app/views/campaigns/uploads_import_leads.js.haml @@ -0,0 +1,6 @@ +- import_id = "campaign_import_leads" + +crm.flick('empty', 'toggle'); +crm.flip_form('#{import_id}'); +$('##{import_id}').html('#{ j render(partial: "import_leads_maps") }'); +crm.set_title('#{import_id}', '#{ j t(import_id) }'); \ No newline at end of file diff --git a/app/views/campaigns/_import.html.haml b/app/views/importers/_import.html.haml similarity index 80% rename from app/views/campaigns/_import.html.haml rename to app/views/importers/_import.html.haml index 8689ca2ea2..cc0ec56244 100644 --- a/app/views/campaigns/_import.html.haml +++ b/app/views/importers/_import.html.haml @@ -1,4 +1,7 @@ -= form_for(@importer, url: import_upload_campaign_path(format: "js"), method: "patch", html: { multipart: true, target: "uploading", onsubmit: "$('#import_submit').disabled = true"}) do |f| += form_for(@importer, + url: import_upload_campaign_path(format: "js"), + method: "patch", + html:{ multipart: true, target: "uploading", onsubmit: "$('#import_submit').disabled = true"}) do |f| = link_to_close new_campaign_path -# todo -#= error_messages_for :avatar, object: @user.avatar, object_name: t('avatar') diff --git a/app/views/importers/_import_leads.html.haml b/app/views/importers/_import_leads.html.haml new file mode 100644 index 0000000000..4e811212b4 --- /dev/null +++ b/app/views/importers/_import_leads.html.haml @@ -0,0 +1,17 @@ += form_for(@importer, + url: uploads_import_leads_campaign_path(@campaign,format: "js"), + method: "patch", + html: { multipart: true, target: "uploading", onsubmit: "$('#import_submit').disabled = true"}) do |f| + = link_to_close campaign_path(@campaign) + %p + %small 'Descripcion aqui' + + %div 'File': + = fields_for(Importer) do |a| + = f.hidden_field :entity_type + %div= a.file_field :attachment + + .buttonbar + = f.submit t(:upload_picture), id: "import_submit" + #{t :or} + = link_to_cancel campaign_path(@campaign) diff --git a/app/views/importers/_import_leads_maps.html.haml b/app/views/importers/_import_leads_maps.html.haml new file mode 100644 index 0000000000..9b221e9de0 --- /dev/null +++ b/app/views/importers/_import_leads_maps.html.haml @@ -0,0 +1 @@ +%div 'File': diff --git a/app/views/campaigns/import.js.haml b/app/views/importers/import.js.haml similarity index 100% rename from app/views/campaigns/import.js.haml rename to app/views/importers/import.js.haml diff --git a/app/views/importers/import_leads.js.haml b/app/views/importers/import_leads.js.haml new file mode 100644 index 0000000000..0a1861c6e7 --- /dev/null +++ b/app/views/importers/import_leads.js.haml @@ -0,0 +1,6 @@ +- import_id = "campaign_import_leads" + +crm.flick('empty', 'toggle'); +crm.flip_form('#{import_id}'); +$('##{import_id}').html('#{ j render(partial: "import_leads") }'); +crm.set_title('#{import_id}', '#{ j t(import_id) }'); diff --git a/app/views/campaigns/import_upload.js.haml b/app/views/importers/import_upload.js.haml similarity index 100% rename from app/views/campaigns/import_upload.js.haml rename to app/views/importers/import_upload.js.haml diff --git a/config/locales/fat_free_crm.en-US.yml b/config/locales/fat_free_crm.en-US.yml index c2484983dc..0f27701fee 100644 --- a/config/locales/fat_free_crm.en-US.yml +++ b/config/locales/fat_free_crm.en-US.yml @@ -937,3 +937,10 @@ en-US: from_to: From %{from} to %{to} from_only: From %{from} to_only: Until %{to} + + + # Import from excel + #---------------------------------------------------------------------------- + import_leads: 'Import Leads' + import_leads_help: 'Todo help for import leads from excel' + xls_file: 'EXCEL File' \ No newline at end of file diff --git a/config/locales/fat_free_crm.es.yml b/config/locales/fat_free_crm.es.yml index cd3f805867..06266194a1 100644 --- a/config/locales/fat_free_crm.es.yml +++ b/config/locales/fat_free_crm.es.yml @@ -916,3 +916,9 @@ es: from_to: De %{from} a %{to} from_only: De %{from} to_only: Antes de %{to} + + # Import from excel + #---------------------------------------------------------------------------- + import_leads: 'Importar clientes potenciales' + import_leads_help: 'Todo help for import leads from excel' + xls_file: 'Fichero EXCEL' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 37f8485217..db230b15b7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -203,13 +203,13 @@ end end + resources :importers do + end + resources :fields, as: :custom_fields resources :fields, as: :core_fields resources :settings, only: :index resources :plugins, only: :index end - - get 'campaigns/import',to: 'campaigns#import', as: :import_campaign - match 'campaigns/import-upload',to: 'campaigns#import_upload', as: :import_upload_campaign, via: %i[put patch] end diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb index 8ab68bf24a..b53adca85a 100644 --- a/lib/fat_free_crm/import_handle.rb +++ b/lib/fat_free_crm/import_handle.rb @@ -10,6 +10,25 @@ module FatFreeCRM class ImportHandle class << self + def get_columns(path) + headers = Hash.new + + puts path + +=begin + xlsx = Roo::Spreadsheet.open(path) + sheet = xlsx.sheets.first + + puts sheet.row(1) + + sheet.row(1).each_with_index { |header, i| + headers[i] = header + } +=end + + return headers + + end def process(importer) result = { items: [], @@ -23,10 +42,17 @@ def process(importer) headers[header] = i } ((sheet.first_row + 1)..sheet.last_row).each do |row| - campaign = Campaign.import_from_xls(sheet.row(row), headers) - result[:items].push(campaign) - if campaign.errors.count - result[:errors].push(campaign.errors.full_messages) + item = nil + if importer.entity_type == 'Campaign' + item = Campaign.import_from_xls(sheet.row(row), headers) + elsif importer.entity_type == 'Lead' + item = Lead.import_from_xls(sheet.row(row), headers) + end + if item + result[:items].push(item) + if item.errors.count + result[:errors].push(item.errors.full_messages) + end end end end From eda70db25cbd4b0afbb384b4c880281359719f74 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sat, 26 Dec 2020 23:58:48 -0500 Subject: [PATCH 09/22] Import new way --- app/controllers/importers_controller.rb | 56 ++++++++++++++++- app/models/polymorphic/importer.rb | 13 +++- app/views/campaigns/_list_title_bar.html.haml | 2 +- app/views/campaigns/index.html.haml | 4 +- app/views/campaigns/show.html.haml | 3 +- app/views/importers/_import.html.haml | 38 ----------- app/views/importers/_import_leads.html.haml | 17 ----- .../importers/_import_leads_maps.html.haml | 1 - app/views/importers/_new.html.haml | 13 ++++ app/views/importers/create.html.haml | 4 ++ .../importers/form_map_columns.html.haml | 16 +++++ app/views/importers/import.js.haml | 6 -- app/views/importers/import_leads.js.haml | 6 -- app/views/importers/import_upload.js.haml | 5 -- app/views/importers/new.js.haml | 6 ++ config/locales/fat_free_crm.en-US.yml | 11 +++- config/locales/fat_free_crm.es.yml | 11 +++- config/routes.rb | 8 ++- db/migrate/20201217030615_create_importers.rb | 13 ++-- db/schema.rb | 13 +++- lib/fat_free_crm/import_handle.rb | 63 +++++++++---------- 21 files changed, 177 insertions(+), 132 deletions(-) delete mode 100644 app/views/importers/_import.html.haml delete mode 100644 app/views/importers/_import_leads.html.haml delete mode 100644 app/views/importers/_import_leads_maps.html.haml create mode 100644 app/views/importers/_new.html.haml create mode 100644 app/views/importers/create.html.haml create mode 100644 app/views/importers/form_map_columns.html.haml delete mode 100644 app/views/importers/import.js.haml delete mode 100644 app/views/importers/import_leads.js.haml delete mode 100644 app/views/importers/import_upload.js.haml create mode 100644 app/views/importers/new.js.haml diff --git a/app/controllers/importers_controller.rb b/app/controllers/importers_controller.rb index 632bfb36e6..560d7c98dd 100644 --- a/app/controllers/importers_controller.rb +++ b/app/controllers/importers_controller.rb @@ -6,7 +6,61 @@ # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php #------------------------------------------------------------------------------ +require 'json' + class ImportersController < ApplicationController + # get /importers/new AJAX + #---------------------------------------------------------------------------- + def new + @importer = Importer.new + @importer.entity_type = params[:entity_type] + if params[:entity_id] + @importer.entity_id = params[:entity_id] + end + respond_with(@importer) + end + + # post /importers/create + #---------------------------------------------------------------------------- + def create + error = false + if params[:importer] + @importer = Importer.create(importer_params) + if @importer.valid? + @importer.save + redirect_to form_map_columns_importer_path(@importer) + else + error = @importer.errors.full_messages + end + end +# Todo + # respond_to do |format| + # format.html { render "create", :locals => {error: error, columns: columns} } + # end + end + + # get /importers/:id/map + #---------------------------------------------------------------------------- + def form_map_columns + @importer = Importer.find(params[:id]) + columns = FatFreeCRM::ImportHandle.get_columns(@importer.attachment.path) + + respond_to do |format| + format.html { render "form_map_columns", :locals => {columns: columns} } + end + end + + # post /importers/:id/map + #---------------------------------------------------------------------------- + def map_columns + @importer = Importer.find(params[:id]) + @importer.status = :map + map = params[:map] + @importer.map = map.to_json + @importer.save + result = FatFreeCRM::ImportHandle.process(@importer) + + end =begin # get /campaigns/import AJAX @@ -103,6 +157,6 @@ def create private def importer_params - params.require(:importer).permit(:attachment,:entity_type,:entity_id) + params.require(:importer).permit(:attachment, :entity_type, :entity_id) end end diff --git a/app/models/polymorphic/importer.rb b/app/models/polymorphic/importer.rb index 579dd0483f..a6ef58ee67 100644 --- a/app/models/polymorphic/importer.rb +++ b/app/models/polymorphic/importer.rb @@ -3,7 +3,8 @@ # Table name: importers # # id :integer not null, primary key -# entity_type :string +# entity_type :string +# entity_id :integer # attachment_file_size :integer # attachment_file_name :string(255) # attachment_content_type :string(255) @@ -11,9 +12,8 @@ # created_at :datetime # updated_at :datetime # - class Importer < ActiveRecord::Base - attr_accessor :status, :entity_type + attribute :entity_attrs has_attached_file :attachment, :path => ":rails_root/public/importers/:id/:filename" @@ -25,6 +25,13 @@ class Importer < ActiveRecord::Base :message => 'Only EXCEL files are allowed.' validates_attachment_file_name :attachment, matches: [/\.xls/, /\.xlsx?$/] + def entity_attrs + attrs = [] + if self.entity_type == 'campaign' + attrs = %w(user_id assigned_to name access status budget target_leads target_conversion target_revenue leads_count opportunities_count revenue starts_on ends_on objectives deleted_at created_at updated_at background_info) + end + attrs + end ActiveSupport.run_load_hooks(:fat_free_crm_importer, self) end diff --git a/app/views/campaigns/_list_title_bar.html.haml b/app/views/campaigns/_list_title_bar.html.haml index 04860525d9..201f3f0ccf 100644 --- a/app/views/campaigns/_list_title_bar.html.haml +++ b/app/views/campaigns/_list_title_bar.html.haml @@ -7,7 +7,7 @@ .create_asset = link_to_inline("create_#{model_name}".to_sym, send("new_#{model_name}_path"), text: t("create_#{model_name}".to_sym)) .import_asset - = link_to_inline("import_#{model_name}".to_sym, send("import_#{model_name}_path"), text: t("import_#{model_name}".to_sym)) + = link_to_inline(:new_importer, new_importer_path(:campaign), text: t(:import_campaigns)) .title %span{id: "create_#{model_name}_title"} #{t controller_name.to_sym} diff --git a/app/views/campaigns/index.html.haml b/app/views/campaigns/index.html.haml index 533b43f27d..5318765377 100644 --- a/app/views/campaigns/index.html.haml +++ b/app/views/campaigns/index.html.haml @@ -3,9 +3,7 @@ = render 'list_title_bar' .remote#create_campaign{ hidden } -.remote#campaign_import{ hidden } - -%iframe#uploading{ name: "uploading", style: "width:100px; height:10px; border:5px" } +.remote#new_importer{ hidden } = render 'search' diff --git a/app/views/campaigns/show.html.haml b/app/views/campaigns/show.html.haml index 7f56d7de46..da5639da0d 100755 --- a/app/views/campaigns/show.html.haml +++ b/app/views/campaigns/show.html.haml @@ -9,8 +9,7 @@ = render 'campaigns/title_bar', campaign: @campaign = render "comments/new", commentable: @campaign - .remote#campaign_import_leads{ hidden } - %iframe#uploading{ name: "uploading", style: "width:100px; height:10px; border:5px" } + .remote#create_importer{ hidden } = render partial: "shared/timeline", collection: @timeline diff --git a/app/views/importers/_import.html.haml b/app/views/importers/_import.html.haml deleted file mode 100644 index cc0ec56244..0000000000 --- a/app/views/importers/_import.html.haml +++ /dev/null @@ -1,38 +0,0 @@ -= form_for(@importer, - url: import_upload_campaign_path(format: "js"), - method: "patch", - html:{ multipart: true, target: "uploading", onsubmit: "$('#import_submit').disabled = true"}) do |f| - = link_to_close new_campaign_path - -# todo - -#= error_messages_for :avatar, object: @user.avatar, object_name: t('avatar') - %p - %small 'Descripcion aqui' - - %div 'File': - = fields_for(Importer) do |a| - %div= a.file_field :attachment - - .buttonbar - = f.submit t(:upload_picture), id: "import_submit" - #{t :or} - = link_to_cancel new_campaign_path - --#= simple_form_for(@campaign, html: one_submit_only, remote: true) do |f| --# = link_to_close new_campaign_path --# = f.hidden_field :user_id --# --# = f.error_messages object_name: t('campaign') --# --# .section --# %table --# %tr --# %td(colspan="5") --# .label.top.req 'File': --# = f.file_field :file, autofocus: true, style: "width:500px" --# --# = hook(:entity_form, self, {f: f, entity: @campaign}) --# --# .buttonbar --# = f.submit 'Import campaign' --# #{t :or} --# = link_to_cancel new_campaign_path \ No newline at end of file diff --git a/app/views/importers/_import_leads.html.haml b/app/views/importers/_import_leads.html.haml deleted file mode 100644 index 4e811212b4..0000000000 --- a/app/views/importers/_import_leads.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -= form_for(@importer, - url: uploads_import_leads_campaign_path(@campaign,format: "js"), - method: "patch", - html: { multipart: true, target: "uploading", onsubmit: "$('#import_submit').disabled = true"}) do |f| - = link_to_close campaign_path(@campaign) - %p - %small 'Descripcion aqui' - - %div 'File': - = fields_for(Importer) do |a| - = f.hidden_field :entity_type - %div= a.file_field :attachment - - .buttonbar - = f.submit t(:upload_picture), id: "import_submit" - #{t :or} - = link_to_cancel campaign_path(@campaign) diff --git a/app/views/importers/_import_leads_maps.html.haml b/app/views/importers/_import_leads_maps.html.haml deleted file mode 100644 index 9b221e9de0..0000000000 --- a/app/views/importers/_import_leads_maps.html.haml +++ /dev/null @@ -1 +0,0 @@ -%div 'File': diff --git a/app/views/importers/_new.html.haml b/app/views/importers/_new.html.haml new file mode 100644 index 0000000000..0f36895ea4 --- /dev/null +++ b/app/views/importers/_new.html.haml @@ -0,0 +1,13 @@ += form_for(@importer, url: create_importer_path, html:{ multipart: true}) do |f| + = f.hidden_field :entity_type + - if @importer.entity_id + = f.hidden_field :entity_id + %p + %small #{t :importer_description} + + %div #{t :xls_file} + = fields_for(Importer) do |a| + %div= a.file_field :attachment + + .buttonbar + = f.submit t(:upload_file) \ No newline at end of file diff --git a/app/views/importers/create.html.haml b/app/views/importers/create.html.haml new file mode 100644 index 0000000000..d331299372 --- /dev/null +++ b/app/views/importers/create.html.haml @@ -0,0 +1,4 @@ +- if error + .flash_error = error +- else + #{ render(partial: "map_columns" ) } \ No newline at end of file diff --git a/app/views/importers/form_map_columns.html.haml b/app/views/importers/form_map_columns.html.haml new file mode 100644 index 0000000000..37391bee64 --- /dev/null +++ b/app/views/importers/form_map_columns.html.haml @@ -0,0 +1,16 @@ += form_for(@importer, url: map_columns_importer_path(@importer), html: { method: :post }) do |f| + = f.hidden_field :id + + %p #{t :map_columns_description} + + %div + %table + - @importer.entity_attrs.each do |attr| + %tr + %td + .label #{ attr } + %td + = select_tag "map[#{ attr }]", options_for_select(columns), class: 'select2', :include_blank => true, id: "map_#{ attr }" + + .buttonbar + = f.submit t(:save) diff --git a/app/views/importers/import.js.haml b/app/views/importers/import.js.haml deleted file mode 100644 index b380bc4ab6..0000000000 --- a/app/views/importers/import.js.haml +++ /dev/null @@ -1,6 +0,0 @@ -- import_id = "campaign_import" - -crm.flick('empty', 'toggle'); -crm.flip_form('#{import_id}'); -$('##{import_id}').html('#{ j render(partial: "import") }'); -crm.set_title('#{import_id}', '#{ j t(import_id) }'); diff --git a/app/views/importers/import_leads.js.haml b/app/views/importers/import_leads.js.haml deleted file mode 100644 index 0a1861c6e7..0000000000 --- a/app/views/importers/import_leads.js.haml +++ /dev/null @@ -1,6 +0,0 @@ -- import_id = "campaign_import_leads" - -crm.flick('empty', 'toggle'); -crm.flip_form('#{import_id}'); -$('##{import_id}').html('#{ j render(partial: "import_leads") }'); -crm.set_title('#{import_id}', '#{ j t(import_id) }'); diff --git a/app/views/importers/import_upload.js.haml b/app/views/importers/import_upload.js.haml deleted file mode 100644 index 705a07dadb..0000000000 --- a/app/views/importers/import_upload.js.haml +++ /dev/null @@ -1,5 +0,0 @@ -- if not @error - $('#campaign_import').html('#{ j render(partial: "import") }'); -- else - $('#campaign_import').html('#{ j render(partial: "import") }'); - $('#campaign_import').effect("shake", { duration:250, distance: 6 }); diff --git a/app/views/importers/new.js.haml b/app/views/importers/new.js.haml new file mode 100644 index 0000000000..f6e50ef2e0 --- /dev/null +++ b/app/views/importers/new.js.haml @@ -0,0 +1,6 @@ +- _id = "new_importer" + +crm.flick('empty', 'toggle'); +crm.flip_form('#{_id}'); +$('##{_id}').html('#{ j render(partial: "new" ) }'); +crm.set_title('#{_id}', '#{ j t(_id) }'); diff --git a/config/locales/fat_free_crm.en-US.yml b/config/locales/fat_free_crm.en-US.yml index 0f27701fee..fb29f32547 100644 --- a/config/locales/fat_free_crm.en-US.yml +++ b/config/locales/fat_free_crm.en-US.yml @@ -941,6 +941,11 @@ en-US: # Import from excel #---------------------------------------------------------------------------- - import_leads: 'Import Leads' - import_leads_help: 'Todo help for import leads from excel' - xls_file: 'EXCEL File' \ No newline at end of file + import_campaigns: Import Campaigns + import_leads: Import Leads + import_leads_help: Todo help for import leads from excel + xls_file: EXCEL File + upload_file: Upload file + save: Save + importer_description: Upload excel file to import its content to the databases. Only valid excel files are allowed. + map_columns_description: Link the excel column that corresponds to each attribute or leave it blank. \ No newline at end of file diff --git a/config/locales/fat_free_crm.es.yml b/config/locales/fat_free_crm.es.yml index 06266194a1..ad9c1c0b0c 100644 --- a/config/locales/fat_free_crm.es.yml +++ b/config/locales/fat_free_crm.es.yml @@ -919,6 +919,11 @@ es: # Import from excel #---------------------------------------------------------------------------- - import_leads: 'Importar clientes potenciales' - import_leads_help: 'Todo help for import leads from excel' - xls_file: 'Fichero EXCEL' \ No newline at end of file + import_campaigns: Importar Campañas + import_leads: Importar clientes potenciales + import_leads_help: Todo help for import leads from excel + xls_file: Fichero EXCEL + upload_file: Subir fichero + save: Guardar + importer_description: Subir fichero excel para importar su contenido a las base de datos. Solo se admiten fichero excel validos. + map_columns_description: Enlazar la columna del excel que le corresponde a cada atributo o dejar en blanco. diff --git a/config/routes.rb b/config/routes.rb index db230b15b7..9071fa58ed 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -203,13 +203,15 @@ end end - resources :importers do - end - resources :fields, as: :custom_fields resources :fields, as: :core_fields resources :settings, only: :index resources :plugins, only: :index end + + get 'importers/new/:entity_type(/:entity_id)' => 'importers#new', as: :new_importer + post 'importers' => 'importers#create', as: :create_importer + get 'importers/:id/map' => 'importers#form_map_columns', as: :form_map_columns_importer + post 'importers/:id/map' => 'importers#map_columns', as: :map_columns_importer end diff --git a/db/migrate/20201217030615_create_importers.rb b/db/migrate/20201217030615_create_importers.rb index c9630dfbea..e77f7b7777 100644 --- a/db/migrate/20201217030615_create_importers.rb +++ b/db/migrate/20201217030615_create_importers.rb @@ -3,11 +3,14 @@ class CreateImporters < ActiveRecord::Migration[4.2] def self.up create_table :importers do |t| - t.integer :attachment_file_size # Uploaded file size - t.string :attachment_file_name # Uploaded full file name - t.string :attachment_content_type # MIME content type - t.string :entity_type # led, campaign - t.string :status # new, success, error + t.integer :attachment_file_size # Uploaded file size + t.string :attachment_file_name, null: false # Uploaded full file name + t.string :attachment_content_type # MIME content type + t.string :entity_type, null: false # led, campaign + t.string :entity_id # led, campaign + t.string :status, null: false, default: :new # new, map , imported , error + t.text :map + t.text :messages t.timestamps end end diff --git a/db/schema.rb b/db/schema.rb index e4be7b7eab..50ff8c1b0b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,6 +11,10 @@ # It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema.define(version: 2020_12_17_030615) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + create_table "account_contacts", id: :serial, force: :cascade do |t| t.integer "account_id" t.integer "contact_id" @@ -249,10 +253,13 @@ create_table "importers", id: :serial, force: :cascade do |t| t.integer "attachment_file_size" - t.string "attachment_file_name" + t.string "attachment_file_name", null: false t.string "attachment_content_type" - t.string "entity_type" - t.string "status" + t.string "entity_type", null: false + t.string "entity_id" + t.string "status", default: "new", null: false + t.text "map" + t.text "messages" t.datetime "created_at" t.datetime "updated_at" end diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb index b53adca85a..f2418367af 100644 --- a/lib/fat_free_crm/import_handle.rb +++ b/lib/fat_free_crm/import_handle.rb @@ -10,54 +10,53 @@ module FatFreeCRM class ImportHandle class << self + def get_columns(path) headers = Hash.new - - puts path - -=begin xlsx = Roo::Spreadsheet.open(path) - sheet = xlsx.sheets.first - - puts sheet.row(1) - + sheet = xlsx.sheet(0) sheet.row(1).each_with_index { |header, i| - headers[i] = header + headers[header] = i } -=end - - return headers - + headers end + def process(importer) - result = { - items: [], - errors: [] - } + errors = [] + map = JSON.parse(importer.map) xlsx = Roo::Spreadsheet.open(importer.attachment.path) xlsx.each_with_pagename do |name, sheet| - headers = Hash.new - sheet.row(1).each_with_index { |header, i| - headers[header] = i - } + # headers = Hash.new + # sheet.row(1).each_with_index { |header, i| + # headers[header] = i + # } ((sheet.first_row + 1)..sheet.last_row).each do |row| - item = nil - if importer.entity_type == 'Campaign' - item = Campaign.import_from_xls(sheet.row(row), headers) - elsif importer.entity_type == 'Lead' - item = Lead.import_from_xls(sheet.row(row), headers) - end - if item - result[:items].push(item) - if item.errors.count - result[:errors].push(item.errors.full_messages) + item = importer.entity_type.constantize.new + + map.each do |att,i| + if i + value = sheet.row(i) + item.instance_variable_set("@#{att}".to_sym, value) end end + if item.valid? + item.save + else + errors << @importer.errors.full_messages + end end end - result + if len(errors) == 0 + importer.status = :imported + else + importer.status = :error + importer.messages = errors.to_json + end + importer.save + + importer end end end From 1c2ef558c5629a53b7af5cdacfab23a2117a6438 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sun, 27 Dec 2020 00:50:25 -0500 Subject: [PATCH 10/22] Import OK --- lib/fat_free_crm/import_handle.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb index f2418367af..ab6a6804e1 100644 --- a/lib/fat_free_crm/import_handle.rb +++ b/lib/fat_free_crm/import_handle.rb @@ -27,32 +27,32 @@ def process(importer) xlsx = Roo::Spreadsheet.open(importer.attachment.path) xlsx.each_with_pagename do |name, sheet| - # headers = Hash.new - # sheet.row(1).each_with_index { |header, i| - # headers[header] = i - # } ((sheet.first_row + 1)..sheet.last_row).each do |row| - item = importer.entity_type.constantize.new - + #item = importer.entity_type.capitalize().constantize.new + values = {} map.each do |att,i| - if i - value = sheet.row(i) - item.instance_variable_set("@#{att}".to_sym, value) + if not i.empty? and i.to_i >= 0 + value = sheet.row(row)[i.to_i] + values[att] = value + #item.instance_variable_set(:@attributes, {att => value}) end end + item = importer.entity_type.capitalize().constantize.create(values) if item.valid? item.save else - errors << @importer.errors.full_messages + errors << item.errors.full_messages end end end - if len(errors) == 0 + if errors.length() == 0 importer.status = :imported else importer.status = :error importer.messages = errors.to_json + puts 'Errors' + puts errors.to_json end importer.save From 02bcb6284d4a949aea620e43357f89940a96ca85 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sun, 27 Dec 2020 12:22:30 -0500 Subject: [PATCH 11/22] Import 'campaign' OK --- app/controllers/importers_controller.rb | 23 +++++++++++++++-------- app/models/polymorphic/importer.rb | 16 +++++++++++++--- app/views/importers/create.html.haml | 5 +++-- app/views/importers/map_columns.html.haml | 4 ++++ config/locales/fat_free_crm.en-US.yml | 3 ++- config/locales/fat_free_crm.es.yml | 1 + lib/fat_free_crm/import_handle.rb | 5 +---- 7 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 app/views/importers/map_columns.html.haml diff --git a/app/controllers/importers_controller.rb b/app/controllers/importers_controller.rb index 560d7c98dd..703882f5c1 100644 --- a/app/controllers/importers_controller.rb +++ b/app/controllers/importers_controller.rb @@ -23,20 +23,24 @@ def new # post /importers/create #---------------------------------------------------------------------------- def create - error = false + errors = false if params[:importer] @importer = Importer.create(importer_params) if @importer.valid? @importer.save - redirect_to form_map_columns_importer_path(@importer) else - error = @importer.errors.full_messages + errors = @importer.errors.full_messages end end -# Todo - # respond_to do |format| - # format.html { render "create", :locals => {error: error, columns: columns} } - # end + + respond_to do |format| + if errors + format.html { render "create", :locals => {errors: errors} } + else + format.html { redirect_to form_map_columns_importer_path(@importer) } + end + end + end # get /importers/:id/map @@ -58,8 +62,11 @@ def map_columns map = params[:map] @importer.map = map.to_json @importer.save - result = FatFreeCRM::ImportHandle.process(@importer) + @importer = FatFreeCRM::ImportHandle.process(@importer) + respond_to do |format| + format.html { render "map_columns" } + end end =begin diff --git a/app/models/polymorphic/importer.rb b/app/models/polymorphic/importer.rb index a6ef58ee67..c8a2eedca1 100644 --- a/app/models/polymorphic/importer.rb +++ b/app/models/polymorphic/importer.rb @@ -12,13 +12,13 @@ # created_at :datetime # updated_at :datetime # +require 'json' class Importer < ActiveRecord::Base attribute :entity_attrs has_attached_file :attachment, :path => ":rails_root/public/importers/:id/:filename" - # validates_attachment :attachment, presence: true, - # content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'] } + validates_attachment :attachment, presence: true validates_attachment_content_type :attachment, :content_type => %w(text/xml application/xml application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/x-ole-storage), @@ -27,11 +27,21 @@ class Importer < ActiveRecord::Base def entity_attrs attrs = [] - if self.entity_type == 'campaign' + case self.entity_type + when 'campaign' attrs = %w(user_id assigned_to name access status budget target_leads target_conversion target_revenue leads_count opportunities_count revenue starts_on ends_on objectives deleted_at created_at updated_at background_info) + when 'lead' + attrs = %w(user_id assigned_to first_name last_name access title company source status referred_by email alt_email phone mobile blog linkedin facebook twitter rating do_not_call deleted_at created_at updated_at background_info skype) + else + # Todo + puts "Error: entity_type not found" end attrs end + def get_messages() + JSON.parse(messages) + end + ActiveSupport.run_load_hooks(:fat_free_crm_importer, self) end diff --git a/app/views/importers/create.html.haml b/app/views/importers/create.html.haml index d331299372..ab6924e17a 100644 --- a/app/views/importers/create.html.haml +++ b/app/views/importers/create.html.haml @@ -1,4 +1,5 @@ -- if error - .flash_error = error +- if errors + - errors.each do |error| + .flash_error #{ error } - else #{ render(partial: "map_columns" ) } \ No newline at end of file diff --git a/app/views/importers/map_columns.html.haml b/app/views/importers/map_columns.html.haml new file mode 100644 index 0000000000..a7e3866cbe --- /dev/null +++ b/app/views/importers/map_columns.html.haml @@ -0,0 +1,4 @@ +%div #{t :importer_status_label } #{ @importer.status } +- @importer.get_messages.each do |message| + %div #{message} + diff --git a/config/locales/fat_free_crm.en-US.yml b/config/locales/fat_free_crm.en-US.yml index fb29f32547..8206ece56c 100644 --- a/config/locales/fat_free_crm.en-US.yml +++ b/config/locales/fat_free_crm.en-US.yml @@ -948,4 +948,5 @@ en-US: upload_file: Upload file save: Save importer_description: Upload excel file to import its content to the databases. Only valid excel files are allowed. - map_columns_description: Link the excel column that corresponds to each attribute or leave it blank. \ No newline at end of file + map_columns_description: Link the excel column that corresponds to each attribute or leave it blank. + importer_status_label: Status \ No newline at end of file diff --git a/config/locales/fat_free_crm.es.yml b/config/locales/fat_free_crm.es.yml index ad9c1c0b0c..1362a0d297 100644 --- a/config/locales/fat_free_crm.es.yml +++ b/config/locales/fat_free_crm.es.yml @@ -927,3 +927,4 @@ es: save: Guardar importer_description: Subir fichero excel para importar su contenido a las base de datos. Solo se admiten fichero excel validos. map_columns_description: Enlazar la columna del excel que le corresponde a cada atributo o dejar en blanco. + importer_status_label: Estado diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb index ab6a6804e1..f995f870c2 100644 --- a/lib/fat_free_crm/import_handle.rb +++ b/lib/fat_free_crm/import_handle.rb @@ -6,6 +6,7 @@ # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php #------------------------------------------------------------------------------ require 'roo' +require 'json' module FatFreeCRM class ImportHandle @@ -28,13 +29,11 @@ def process(importer) xlsx.each_with_pagename do |name, sheet| ((sheet.first_row + 1)..sheet.last_row).each do |row| - #item = importer.entity_type.capitalize().constantize.new values = {} map.each do |att,i| if not i.empty? and i.to_i >= 0 value = sheet.row(row)[i.to_i] values[att] = value - #item.instance_variable_set(:@attributes, {att => value}) end end item = importer.entity_type.capitalize().constantize.create(values) @@ -51,8 +50,6 @@ def process(importer) else importer.status = :error importer.messages = errors.to_json - puts 'Errors' - puts errors.to_json end importer.save From 08a567e75532e978d7db5d6da748e19c07d2561a Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sun, 27 Dec 2020 12:29:42 -0500 Subject: [PATCH 12/22] Import 'lead' OK --- app/views/campaigns/_title_bar.html.haml | 2 +- app/views/campaigns/show.html.haml | 2 +- lib/fat_free_crm/import_handle.rb | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/views/campaigns/_title_bar.html.haml b/app/views/campaigns/_title_bar.html.haml index 71c82814b3..1a2013aeed 100644 --- a/app/views/campaigns/_title_bar.html.haml +++ b/app/views/campaigns/_title_bar.html.haml @@ -2,7 +2,7 @@ .title_tools#menu = link_to_inline(:edit_campaign, edit_campaign_path(@campaign), text: t(:edit)) + " | " = link_to_function(t(:delete) + '?', confirm_delete(@campaign)) + " | " - = link_to_inline(:import_leads, import_leads_campaign_path(@campaign), text: t("import_leads".to_sym)) + = link_to_inline(:new_importer, new_importer_path(:lead,@campaign), text: t(:import_leads)) .title_tools#buttons = view_buttons diff --git a/app/views/campaigns/show.html.haml b/app/views/campaigns/show.html.haml index da5639da0d..9a26c92c3d 100755 --- a/app/views/campaigns/show.html.haml +++ b/app/views/campaigns/show.html.haml @@ -9,7 +9,7 @@ = render 'campaigns/title_bar', campaign: @campaign = render "comments/new", commentable: @campaign - .remote#create_importer{ hidden } + .remote#new_importer{ hidden } = render partial: "shared/timeline", collection: @timeline diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb index f995f870c2..42410e2a1e 100644 --- a/lib/fat_free_crm/import_handle.rb +++ b/lib/fat_free_crm/import_handle.rb @@ -36,7 +36,13 @@ def process(importer) values[att] = value end end - item = importer.entity_type.capitalize().constantize.create(values) + + # Todo Do this more geneic + if importer.entity_type == 'lead' + values[:campaign_id] = importer.entity_id + end + + item = importer.entity_type.capitalize.constantize.create(values) if item.valid? item.save else @@ -45,7 +51,7 @@ def process(importer) end end - if errors.length() == 0 + if errors.length == 0 importer.status = :imported else importer.status = :error From 889db48a0aea469dc89097890b630e88ef3c7cdf Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sun, 27 Dec 2020 12:35:08 -0500 Subject: [PATCH 13/22] Restore model lead an campaning --- app/models/entities/campaign.rb | 20 -------------------- app/models/entities/lead.rb | 8 -------- 2 files changed, 28 deletions(-) diff --git a/app/models/entities/campaign.rb b/app/models/entities/campaign.rb index 96c959f912..460a29c238 100644 --- a/app/models/entities/campaign.rb +++ b/app/models/entities/campaign.rb @@ -98,26 +98,6 @@ def discard!(attachment) end end - # Save Campaign from row in xls - def self.import_from_xls(row,headers) - campaign = Campaign.new - campaign.name = row[headers['Name']] - campaign.access = row[headers['Access']] - campaign.status = row[headers['Status']] - campaign.budget =row[headers['Budget']] - campaign.target_leads =row[headers['target leads']] - campaign.target_conversion =row[headers['Target conversion']] - campaign.leads_count =row[headers['Number of leads']] - campaign.opportunities_count =row[headers['Total Opportunities']] - campaign.revenue =row[headers['target revenue']] - campaign.starts_on =row[headers['start date']] - campaign.ends_on =row[headers['end date']] - campaign.objectives =row[headers['Objectives']] - campaign.background_info =row[headers['Background']] - campaign.save - campaign - end - private # Make sure end date > start date. diff --git a/app/models/entities/lead.rb b/app/models/entities/lead.rb index 6d7074da62..680449f441 100644 --- a/app/models/entities/lead.rb +++ b/app/models/entities/lead.rb @@ -165,14 +165,6 @@ def full_name(format = nil) end alias name full_name - # Save Campaign from row in xls - def self.import_from_xls(row,headers) - lead = Lead.new - lead.name = row[headers['Name']] - lead.save - lead - end - private #---------------------------------------------------------------------------- From c9c21170658149c3ae534d87aacdaee02924dee4 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sun, 27 Dec 2020 12:38:53 -0500 Subject: [PATCH 14/22] Remove unused files --- .../campaigns/uploads_import_leads.js.haml | 6 -- lib/tasks/ffcrm/import.rake | 63 ------------------- 2 files changed, 69 deletions(-) delete mode 100644 app/views/campaigns/uploads_import_leads.js.haml delete mode 100644 lib/tasks/ffcrm/import.rake diff --git a/app/views/campaigns/uploads_import_leads.js.haml b/app/views/campaigns/uploads_import_leads.js.haml deleted file mode 100644 index ce24a34d64..0000000000 --- a/app/views/campaigns/uploads_import_leads.js.haml +++ /dev/null @@ -1,6 +0,0 @@ -- import_id = "campaign_import_leads" - -crm.flick('empty', 'toggle'); -crm.flip_form('#{import_id}'); -$('##{import_id}').html('#{ j render(partial: "import_leads_maps") }'); -crm.set_title('#{import_id}', '#{ j t(import_id) }'); \ No newline at end of file diff --git a/lib/tasks/ffcrm/import.rake b/lib/tasks/ffcrm/import.rake deleted file mode 100644 index 3681cf3e2b..0000000000 --- a/lib/tasks/ffcrm/import.rake +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -# Copyright (c) 2008-2013 Michael Dvorkin and contributors. -# -# Fat Free CRM is freely distributable under the terms of MIT license. -# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php -#------------------------------------------------------------------------------ -namespace :ffcrm do - namespace :import do - desc "Import files..." - task process: :environment do - require 'roo' - - importers = Importer.all - importers.each do |importer| - require 'roo' - - xlsx = Roo::Spreadsheet.open(importer.attachment.path, extension: :xls) - - xlsx.each_with_pagename do |name, sheet| - headers = Hash.new - sheet.row(1).each_with_index {|header,i| - headers[header] = i - } - - ((sheet.first_row + 1)..sheet.last_row).each do |row| - campaign = Campaign.new - campaign.name = sheet.row(row)[headers['Name']] - campaign.access = sheet.row(row)[headers['Access']] - campaign.status = sheet.row(row)[headers['Status']] - campaign.budget =sheet.row(row)[headers['Budget']] - campaign.target_leads =sheet.row(row)[headers['target leads']] - campaign.target_conversion =sheet.row(row)[headers['Target conversion']] - campaign.leads_count =sheet.row(row)[headers['Number of leads']] - campaign.opportunities_count =sheet.row(row)[headers['Total Opportunities']] - campaign.revenue =sheet.row(row)[headers['target revenue']] - campaign.starts_on =sheet.row(row)[headers['start date']] - campaign.ends_on =sheet.row(row)[headers['end date']] - campaign.objectives =sheet.row(row)[headers['Objectives']] - campaign.background_info =sheet.row(row)[headers['Background']] - if campaign.save - puts 'Saved' - else - puts campaign.errors.full_messages - end - - - # headers.each do |header, i | - # value = sheet.row(row)[i] - # end - end - - # sheet.each_row(offset: 1) do |row| # skip first row - # puts row - # end - end - - - puts - end - end - end -end From 0e4e7382a3a95475e07d539e9ca54b3468b62c46 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sun, 27 Dec 2020 12:45:56 -0500 Subject: [PATCH 15/22] Restore permission in vendor --- .../assets/images/calendar_date_select/calendar.gif | Bin vendor/assets/images/chosen-sprite.png | Bin .../images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png | Bin .../images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png | Bin .../jquery-ui/ui-bg_flat_100_ffffff_40x100.png | Bin .../jquery-ui/ui-bg_flat_25_3875d7_40x100.png | Bin .../jquery-ui/ui-bg_flat_55_ffffff_40x100.png | Bin .../jquery-ui/ui-bg_flat_65_3875d7_40x100.png | Bin .../jquery-ui/ui-bg_flat_75_ffffff_40x100.png | Bin .../ui-bg_highlight-soft_50_dddddd_1x100.png | Bin .../images/jquery-ui/ui-icons_0073ea_256x240.png | Bin .../images/jquery-ui/ui-icons_466bb1_256x240.png | Bin .../images/jquery-ui/ui-icons_ff0084_256x240.png | Bin vendor/assets/javascripts/jquery.disable.js | 0 vendor/assets/javascripts/jquery_timeago/index.js | 0 .../javascripts/jquery_timeago/jquery.timeago.cz.js | 0 .../javascripts/jquery_timeago/jquery.timeago.de.js | 0 .../jquery_timeago/jquery.timeago.en-GB.js | 0 .../jquery_timeago/jquery.timeago.en-US.js | 0 .../jquery_timeago/jquery.timeago.es-CL.js | 0 .../javascripts/jquery_timeago/jquery.timeago.es.js | 0 .../jquery_timeago/jquery.timeago.fr-CA.js | 0 .../javascripts/jquery_timeago/jquery.timeago.fr.js | 0 .../javascripts/jquery_timeago/jquery.timeago.it.js | 0 .../javascripts/jquery_timeago/jquery.timeago.ja.js | 0 .../javascripts/jquery_timeago/jquery.timeago.js | 0 .../javascripts/jquery_timeago/jquery.timeago.nl.js | 0 .../javascripts/jquery_timeago/jquery.timeago.pl.js | 0 .../jquery_timeago/jquery.timeago.pt-BR.js | 0 .../javascripts/jquery_timeago/jquery.timeago.ru.js | 0 .../jquery_timeago/jquery.timeago.sv-SE.js | 0 .../javascripts/jquery_timeago/jquery.timeago.th.js | 0 .../jquery_timeago/jquery.timeago.zh-CN.js | 0 .../jquery-ui-timepicker-addon.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-af.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-ca.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-cz.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-de.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-el.js | 0 .../jquery-ui-timepicker-es-CL.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-es.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-et.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-fi.js | 0 .../jquery-ui-timepicker-fr-CA.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-fr.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-gl.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-he.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-hu.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-id.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-it.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-ja.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-ko.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-lt.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-nl.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-no.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-pl.js | 0 .../jquery-ui-timepicker-pt-BR.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-pt.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-ro.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-ru.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-sk.js | 0 .../jquery-ui-timepicker-sv-SE.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-th.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-tr.js | 0 .../jquery_ui_datepicker/jquery-ui-timepicker-vi.js | 0 .../jquery-ui-timepicker-zh-CN.js | 0 .../jquery-ui-timepicker-zh-TW.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-cz.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-de.js | 0 .../jquery.ui.datepicker-en-GB.js | 0 .../jquery.ui.datepicker-es-CL.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-es.js | 0 .../jquery.ui.datepicker-fr-CA.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-fr.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-it.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-ja.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-nl.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-pl.js | 0 .../jquery.ui.datepicker-pt-BR.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-pt.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-ru.js | 0 .../jquery.ui.datepicker-sv-SE.js | 0 .../jquery_ui_datepicker/jquery.ui.datepicker-th.js | 0 .../jquery.ui.datepicker-zh-CN.js | 0 vendor/assets/javascripts/lib/select-parser.coffee | 0 vendor/assets/javascripts/rating.js | 0 vendor/assets/javascripts/textarea_autocomplete.js | 0 vendor/assets/stylesheets/jquery-ui.custom.scss | 0 vendor/assets/stylesheets/modalbox.css | 0 vendor/gems/globby-0.1.2/LICENSE.txt | 0 vendor/gems/globby-0.1.2/README.md | 0 vendor/gems/globby-0.1.2/Rakefile | 0 vendor/gems/globby-0.1.2/lib/globby.rb | 0 vendor/gems/globby-0.1.2/lib/globby/glob.rb | 0 vendor/gems/globby-0.1.2/lib/globby/globject.rb | 0 vendor/gems/globby-0.1.2/lib/globby/result.rb | 0 vendor/gems/globby-0.1.2/spec/gitignore_spec.rb | 0 vendor/gems/globby-0.1.2/spec/globby_spec.rb | 0 vendor/gems/ransack_ui-1.3.4/.gitignore | 0 vendor/gems/ransack_ui-1.3.4/Gemfile | 0 vendor/gems/ransack_ui-1.3.4/LICENSE.txt | 0 vendor/gems/ransack_ui-1.3.4/README.md | 0 vendor/gems/ransack_ui-1.3.4/Rakefile | 0 .../app/assets/images/ransack_ui/calendar.png | Bin .../app/assets/images/ransack_ui/delete.png | Bin .../assets/javascripts/ransack/predicates.js.coffee | 0 .../button_group_select.js.coffee | 0 .../ransack_ui_bootstrap/index.js.coffee | 0 .../assets/javascripts/ransack_ui_jquery/index.js | 0 .../ransack_ui_jquery/search_form.js.coffee.erb | 0 .../stylesheets/ransack_ui_bootstrap/index.css | 0 .../ransack_ui_bootstrap/search.css.scss | 0 .../app/views/ransack_ui/_sort_fields.html.erb | 0 vendor/gems/ransack_ui-1.3.4/config/locales/en.yml | 0 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui.rb | 0 .../lib/ransack_ui/adapters/active_record.rb | 0 .../lib/ransack_ui/adapters/active_record/base.rb | 0 .../lib/ransack_ui/controller_helpers.rb | 0 .../ransack_ui-1.3.4/lib/ransack_ui/rails/engine.rb | 0 .../adapters/active_record/base.rb | 0 .../ransack_ui/ransack_overrides/configuration.rb | 0 .../lib/ransack_ui/ransack_overrides/context.rb | 0 .../ransack_overrides/helpers/form_builder.rb | 0 .../ransack_ui/ransack_overrides/nodes/attribute.rb | 0 .../ransack_ui/ransack_overrides/nodes/condition.rb | 0 .../ransack_ui/ransack_overrides/nodes/grouping.rb | 0 .../gems/ransack_ui-1.3.4/lib/ransack_ui/version.rb | 0 .../ransack_ui-1.3.4/lib/ransack_ui/view_helpers.rb | 0 vendor/gems/ransack_ui-1.3.4/ransack_ui.gemspec | 0 129 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 vendor/assets/images/calendar_date_select/calendar.gif mode change 100755 => 100644 vendor/assets/images/chosen-sprite.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_flat_100_ffffff_40x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_flat_25_3875d7_40x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_flat_65_3875d7_40x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-icons_0073ea_256x240.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-icons_466bb1_256x240.png mode change 100755 => 100644 vendor/assets/images/jquery-ui/ui-icons_ff0084_256x240.png mode change 100755 => 100644 vendor/assets/javascripts/jquery.disable.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/index.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.es-CL.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.nl.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-addon.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-af.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ca.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-cz.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-de.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-el.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es-CL.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-et.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fi.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr-CA.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-gl.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-he.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-hu.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-id.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-it.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ja.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ko.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-lt.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-nl.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-no.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pl.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt-BR.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ro.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ru.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sk.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sv-SE.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-th.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-tr.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-vi.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-CN.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-TW.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-cz.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-de.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-en-GB.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es-CL.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr-CA.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-it.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ja.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-nl.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pl.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt-BR.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ru.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-sv-SE.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-th.js mode change 100755 => 100644 vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-zh-CN.js mode change 100755 => 100644 vendor/assets/javascripts/lib/select-parser.coffee mode change 100755 => 100644 vendor/assets/javascripts/rating.js mode change 100755 => 100644 vendor/assets/javascripts/textarea_autocomplete.js mode change 100755 => 100644 vendor/assets/stylesheets/jquery-ui.custom.scss mode change 100755 => 100644 vendor/assets/stylesheets/modalbox.css mode change 100755 => 100644 vendor/gems/globby-0.1.2/LICENSE.txt mode change 100755 => 100644 vendor/gems/globby-0.1.2/README.md mode change 100755 => 100644 vendor/gems/globby-0.1.2/Rakefile mode change 100755 => 100644 vendor/gems/globby-0.1.2/lib/globby.rb mode change 100755 => 100644 vendor/gems/globby-0.1.2/lib/globby/glob.rb mode change 100755 => 100644 vendor/gems/globby-0.1.2/lib/globby/globject.rb mode change 100755 => 100644 vendor/gems/globby-0.1.2/lib/globby/result.rb mode change 100755 => 100644 vendor/gems/globby-0.1.2/spec/gitignore_spec.rb mode change 100755 => 100644 vendor/gems/globby-0.1.2/spec/globby_spec.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/.gitignore mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/Gemfile mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/LICENSE.txt mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/README.md mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/Rakefile mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/calendar.png mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/delete.png mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack/predicates.js.coffee mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/button_group_select.js.coffee mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/index.js.coffee mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/index.js mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/search_form.js.coffee.erb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/index.css mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/search.css.scss mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/app/views/ransack_ui/_sort_fields.html.erb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/config/locales/en.yml mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record/base.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/controller_helpers.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/rails/engine.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/adapters/active_record/base.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/configuration.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/context.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/helpers/form_builder.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/attribute.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/condition.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/grouping.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/version.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/view_helpers.rb mode change 100755 => 100644 vendor/gems/ransack_ui-1.3.4/ransack_ui.gemspec diff --git a/vendor/assets/images/calendar_date_select/calendar.gif b/vendor/assets/images/calendar_date_select/calendar.gif old mode 100755 new mode 100644 diff --git a/vendor/assets/images/chosen-sprite.png b/vendor/assets/images/chosen-sprite.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_100_ffffff_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_100_ffffff_40x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_25_3875d7_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_25_3875d7_40x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_65_3875d7_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_65_3875d7_40x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png b/vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png b/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-icons_0073ea_256x240.png b/vendor/assets/images/jquery-ui/ui-icons_0073ea_256x240.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-icons_466bb1_256x240.png b/vendor/assets/images/jquery-ui/ui-icons_466bb1_256x240.png old mode 100755 new mode 100644 diff --git a/vendor/assets/images/jquery-ui/ui-icons_ff0084_256x240.png b/vendor/assets/images/jquery-ui/ui-icons_ff0084_256x240.png old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery.disable.js b/vendor/assets/javascripts/jquery.disable.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/index.js b/vendor/assets/javascripts/jquery_timeago/index.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es-CL.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es-CL.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.nl.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.nl.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js b/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-addon.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-addon.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-af.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-af.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ca.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ca.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-cz.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-cz.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-de.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-de.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-el.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-el.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es-CL.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es-CL.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-et.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-et.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fi.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fi.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr-CA.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr-CA.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-gl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-gl.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-he.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-he.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-hu.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-hu.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-id.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-id.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-it.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-it.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ja.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ja.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ko.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ko.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-lt.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-lt.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-nl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-nl.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-no.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-no.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pl.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt-BR.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt-BR.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ro.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ro.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ru.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ru.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sk.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sk.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sv-SE.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sv-SE.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-th.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-th.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-tr.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-tr.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-vi.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-vi.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-CN.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-CN.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-TW.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-TW.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-cz.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-cz.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-de.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-de.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-en-GB.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-en-GB.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es-CL.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es-CL.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr-CA.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr-CA.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-it.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-it.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ja.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ja.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-nl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-nl.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pl.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pl.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt-BR.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt-BR.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ru.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ru.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-sv-SE.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-sv-SE.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-th.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-th.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-zh-CN.js b/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-zh-CN.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/lib/select-parser.coffee b/vendor/assets/javascripts/lib/select-parser.coffee old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/rating.js b/vendor/assets/javascripts/rating.js old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/textarea_autocomplete.js b/vendor/assets/javascripts/textarea_autocomplete.js old mode 100755 new mode 100644 diff --git a/vendor/assets/stylesheets/jquery-ui.custom.scss b/vendor/assets/stylesheets/jquery-ui.custom.scss old mode 100755 new mode 100644 diff --git a/vendor/assets/stylesheets/modalbox.css b/vendor/assets/stylesheets/modalbox.css old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/LICENSE.txt b/vendor/gems/globby-0.1.2/LICENSE.txt old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/README.md b/vendor/gems/globby-0.1.2/README.md old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/Rakefile b/vendor/gems/globby-0.1.2/Rakefile old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/lib/globby.rb b/vendor/gems/globby-0.1.2/lib/globby.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/lib/globby/glob.rb b/vendor/gems/globby-0.1.2/lib/globby/glob.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/lib/globby/globject.rb b/vendor/gems/globby-0.1.2/lib/globby/globject.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/lib/globby/result.rb b/vendor/gems/globby-0.1.2/lib/globby/result.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/spec/gitignore_spec.rb b/vendor/gems/globby-0.1.2/spec/gitignore_spec.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/globby-0.1.2/spec/globby_spec.rb b/vendor/gems/globby-0.1.2/spec/globby_spec.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/.gitignore b/vendor/gems/ransack_ui-1.3.4/.gitignore old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/Gemfile b/vendor/gems/ransack_ui-1.3.4/Gemfile old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/LICENSE.txt b/vendor/gems/ransack_ui-1.3.4/LICENSE.txt old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/README.md b/vendor/gems/ransack_ui-1.3.4/README.md old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/Rakefile b/vendor/gems/ransack_ui-1.3.4/Rakefile old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/calendar.png b/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/calendar.png old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/delete.png b/vendor/gems/ransack_ui-1.3.4/app/assets/images/ransack_ui/delete.png old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack/predicates.js.coffee b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack/predicates.js.coffee old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/button_group_select.js.coffee b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/button_group_select.js.coffee old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/index.js.coffee b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_bootstrap/index.js.coffee old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/index.js b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/index.js old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/search_form.js.coffee.erb b/vendor/gems/ransack_ui-1.3.4/app/assets/javascripts/ransack_ui_jquery/search_form.js.coffee.erb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/index.css b/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/index.css old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/search.css.scss b/vendor/gems/ransack_ui-1.3.4/app/assets/stylesheets/ransack_ui_bootstrap/search.css.scss old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/app/views/ransack_ui/_sort_fields.html.erb b/vendor/gems/ransack_ui-1.3.4/app/views/ransack_ui/_sort_fields.html.erb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/config/locales/en.yml b/vendor/gems/ransack_ui-1.3.4/config/locales/en.yml old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record/base.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/adapters/active_record/base.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/controller_helpers.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/controller_helpers.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/rails/engine.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/rails/engine.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/adapters/active_record/base.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/adapters/active_record/base.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/configuration.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/configuration.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/context.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/context.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/helpers/form_builder.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/helpers/form_builder.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/attribute.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/attribute.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/condition.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/condition.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/grouping.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/ransack_overrides/nodes/grouping.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/version.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/version.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/view_helpers.rb b/vendor/gems/ransack_ui-1.3.4/lib/ransack_ui/view_helpers.rb old mode 100755 new mode 100644 diff --git a/vendor/gems/ransack_ui-1.3.4/ransack_ui.gemspec b/vendor/gems/ransack_ui-1.3.4/ransack_ui.gemspec old mode 100755 new mode 100644 From 974cb3a716d7e99326a5d33f2a0edecf49ceb898 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Sun, 27 Dec 2020 21:31:24 -0500 Subject: [PATCH 16/22] Improving select --- app/controllers/importers_controller.rb | 16 +++++++++++++++- app/models/polymorphic/importer.rb | 4 ++++ app/views/importers/form_map_columns.html.haml | 15 ++++++++++++--- config/locales/fat_free_crm.en-US.yml | 2 +- config/locales/fat_free_crm.es.yml | 2 +- 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/app/controllers/importers_controller.rb b/app/controllers/importers_controller.rb index 703882f5c1..08fdb87bf0 100644 --- a/app/controllers/importers_controller.rb +++ b/app/controllers/importers_controller.rb @@ -49,8 +49,22 @@ def form_map_columns @importer = Importer.find(params[:id]) columns = FatFreeCRM::ImportHandle.get_columns(@importer.attachment.path) + attributes = [] + + object = @importer.entity_class + _attrs = object.attribute_names - ['id'] + + _attrs.each do |attr| + attributes.push( + { + name: attr, + required: object.validators_on(attr).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator } + } + ) + end + respond_to do |format| - format.html { render "form_map_columns", :locals => {columns: columns} } + format.html { render "form_map_columns", :locals => {columns: columns, attributes: attributes} } end end diff --git a/app/models/polymorphic/importer.rb b/app/models/polymorphic/importer.rb index c8a2eedca1..6d59b5ff49 100644 --- a/app/models/polymorphic/importer.rb +++ b/app/models/polymorphic/importer.rb @@ -43,5 +43,9 @@ def get_messages() JSON.parse(messages) end + def entity_class + self.entity_type.capitalize.constantize + end + ActiveSupport.run_load_hooks(:fat_free_crm_importer, self) end diff --git a/app/views/importers/form_map_columns.html.haml b/app/views/importers/form_map_columns.html.haml index 37391bee64..74048dd3c3 100644 --- a/app/views/importers/form_map_columns.html.haml +++ b/app/views/importers/form_map_columns.html.haml @@ -5,12 +5,21 @@ %div %table - - @importer.entity_attrs.each do |attr| + - attributes.each do |attr| %tr %td - .label #{ attr } + .label + #{ attr[:name] } + - if attr[:required] + %span.warn * %td - = select_tag "map[#{ attr }]", options_for_select(columns), class: 'select2', :include_blank => true, id: "map_#{ attr }" + = select_tag "map[#{ attr[:name] }]", + options_for_select(columns), + class: 'select2', + include_blank: true, + data: {placeholder: t(:select_blank)}, + required: attr[:required], + id: "map_#{ attr[:name] }" .buttonbar = f.submit t(:save) diff --git a/config/locales/fat_free_crm.en-US.yml b/config/locales/fat_free_crm.en-US.yml index 8206ece56c..38cb857c00 100644 --- a/config/locales/fat_free_crm.en-US.yml +++ b/config/locales/fat_free_crm.en-US.yml @@ -948,5 +948,5 @@ en-US: upload_file: Upload file save: Save importer_description: Upload excel file to import its content to the databases. Only valid excel files are allowed. - map_columns_description: Link the excel column that corresponds to each attribute or leave it blank. + map_columns_description: Link the excel column that corresponds to each attribute or leave it blank. The elements with * must have a value in the column that is selected. importer_status_label: Status \ No newline at end of file diff --git a/config/locales/fat_free_crm.es.yml b/config/locales/fat_free_crm.es.yml index 1362a0d297..9a45704039 100644 --- a/config/locales/fat_free_crm.es.yml +++ b/config/locales/fat_free_crm.es.yml @@ -926,5 +926,5 @@ es: upload_file: Subir fichero save: Guardar importer_description: Subir fichero excel para importar su contenido a las base de datos. Solo se admiten fichero excel validos. - map_columns_description: Enlazar la columna del excel que le corresponde a cada atributo o dejar en blanco. + map_columns_description: Enlazar la columna del excel que le corresponde a cada atributo o dejar en blanco. Los elementos con * tienen que tener valor en la columna que se seleccione. importer_status_label: Estado From ba5edf6ed755e5fc6e3fb8b1318a80795eb31506 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Mon, 28 Dec 2020 17:25:29 -0500 Subject: [PATCH 17/22] Importa address --- app/controllers/importers_controller.rb | 16 ++++++++- app/models/polymorphic/importer.rb | 14 -------- app/views/campaigns/_list_title_bar.html.haml | 2 +- .../importers/form_map_columns.html.haml | 20 +++++++++++ lib/fat_free_crm/import_handle.rb | 35 ++++++++++++++----- 5 files changed, 63 insertions(+), 24 deletions(-) diff --git a/app/controllers/importers_controller.rb b/app/controllers/importers_controller.rb index 08fdb87bf0..a1edbdf153 100644 --- a/app/controllers/importers_controller.rb +++ b/app/controllers/importers_controller.rb @@ -50,6 +50,7 @@ def form_map_columns columns = FatFreeCRM::ImportHandle.get_columns(@importer.attachment.path) attributes = [] + attributes_extra = [] object = @importer.entity_class _attrs = object.attribute_names - ['id'] @@ -63,8 +64,21 @@ def form_map_columns ) end + if @importer.entity_type == 'lead' + _attrs = Address.attribute_names - %w(id created_at updated_at deleted_at address_type addressable_type addressable_id) + + _attrs.each do |attr| + attributes_extra.push( + { + name: attr, + required: Address.validators_on(attr).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator } + } + ) + end + end + respond_to do |format| - format.html { render "form_map_columns", :locals => {columns: columns, attributes: attributes} } + format.html { render "form_map_columns", :locals => {columns: columns, attributes: attributes, attributes_extra: attributes_extra} } end end diff --git a/app/models/polymorphic/importer.rb b/app/models/polymorphic/importer.rb index 6d59b5ff49..1ad83c7185 100644 --- a/app/models/polymorphic/importer.rb +++ b/app/models/polymorphic/importer.rb @@ -25,20 +25,6 @@ class Importer < ActiveRecord::Base :message => 'Only EXCEL files are allowed.' validates_attachment_file_name :attachment, matches: [/\.xls/, /\.xlsx?$/] - def entity_attrs - attrs = [] - case self.entity_type - when 'campaign' - attrs = %w(user_id assigned_to name access status budget target_leads target_conversion target_revenue leads_count opportunities_count revenue starts_on ends_on objectives deleted_at created_at updated_at background_info) - when 'lead' - attrs = %w(user_id assigned_to first_name last_name access title company source status referred_by email alt_email phone mobile blog linkedin facebook twitter rating do_not_call deleted_at created_at updated_at background_info skype) - else - # Todo - puts "Error: entity_type not found" - end - attrs - end - def get_messages() JSON.parse(messages) end diff --git a/app/views/campaigns/_list_title_bar.html.haml b/app/views/campaigns/_list_title_bar.html.haml index 201f3f0ccf..3de3f01ab6 100644 --- a/app/views/campaigns/_list_title_bar.html.haml +++ b/app/views/campaigns/_list_title_bar.html.haml @@ -6,7 +6,7 @@ = view_buttons .create_asset = link_to_inline("create_#{model_name}".to_sym, send("new_#{model_name}_path"), text: t("create_#{model_name}".to_sym)) - .import_asset + .create_asset = link_to_inline(:new_importer, new_importer_path(:campaign), text: t(:import_campaigns)) .title diff --git a/app/views/importers/form_map_columns.html.haml b/app/views/importers/form_map_columns.html.haml index 74048dd3c3..6f41028a9f 100644 --- a/app/views/importers/form_map_columns.html.haml +++ b/app/views/importers/form_map_columns.html.haml @@ -21,5 +21,25 @@ required: attr[:required], id: "map_#{ attr[:name] }" + - if attributes_extra.length + %div.subtitle + #{t :address} + %table + - attributes_extra.each do |attr| + %tr + %td + .label + #{ attr[:name] } + - if attr[:required] + %span.warn * + %td + = select_tag "map[business_address_attributes][#{ attr[:name] }]", + options_for_select(columns), + class: 'select2', + include_blank: true, + data: {placeholder: t(:select_blank)}, + required: attr[:required], + id: "map_#{ attr[:name] }" + .buttonbar = f.submit t(:save) diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb index 42410e2a1e..0cc76f5690 100644 --- a/lib/fat_free_crm/import_handle.rb +++ b/lib/fat_free_crm/import_handle.rb @@ -22,6 +22,20 @@ def get_columns(path) headers end + def get_values(map, sheet, row) + values = {} + map.each do |att, i| + if i.is_a?(Hash) + values[att] = get_values(i, sheet, row) + elsif not i.empty? and i.to_i >= 0 + value = sheet.row(row)[i.to_i] + values[att] = value + end + end + + values + end + def process(importer) errors = [] map = JSON.parse(importer.map) @@ -29,22 +43,27 @@ def process(importer) xlsx.each_with_pagename do |name, sheet| ((sheet.first_row + 1)..sheet.last_row).each do |row| - values = {} - map.each do |att,i| - if not i.empty? and i.to_i >= 0 - value = sheet.row(row)[i.to_i] - values[att] = value - end - end + values = get_values(map, sheet, row) - # Todo Do this more geneic + # TODO Do this more geneic + business_address_attributes = {} if importer.entity_type == 'lead' values[:campaign_id] = importer.entity_id + if values.key?('business_address_attributes') + business_address_attributes = values.delete('business_address_attributes') + end end item = importer.entity_type.capitalize.constantize.create(values) if item.valid? item.save + if importer.entity_type == 'lead' + business_address_attributes["address_type"] = "Business" + business_address_attributes["addressable_type"] = "Lead" + business_address_attributes["addressable_id"] = item.id + address = Address.create(business_address_attributes) + address.save + end else errors << item.errors.full_messages end From 90d1cb8cfd1cd76c68a7643db3d143d677b38187 Mon Sep 17 00:00:00 2001 From: Rubisel Prieto Dupeyron Date: Mon, 28 Dec 2020 17:59:36 -0500 Subject: [PATCH 18/22] Remove plpgsql --- db/schema.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 50ff8c1b0b..ce7a36775c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -12,9 +12,6 @@ ActiveRecord::Schema.define(version: 2020_12_17_030615) do - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - create_table "account_contacts", id: :serial, force: :cascade do |t| t.integer "account_id" t.integer "contact_id" From a803eb861521406636d3fff612f676db19c3bc46 Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Sun, 24 Jan 2021 06:12:17 +0000 Subject: [PATCH 19/22] Add importer spec file Rename importer model into files folder --- app/models/{polymorphic => files}/importer.rb | 0 spec/models/files/importer_spec.rb | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+) rename app/models/{polymorphic => files}/importer.rb (100%) create mode 100644 spec/models/files/importer_spec.rb diff --git a/app/models/polymorphic/importer.rb b/app/models/files/importer.rb similarity index 100% rename from app/models/polymorphic/importer.rb rename to app/models/files/importer.rb diff --git a/spec/models/files/importer_spec.rb b/spec/models/files/importer_spec.rb new file mode 100644 index 0000000000..79d6ca96d6 --- /dev/null +++ b/spec/models/files/importer_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ +# == Schema Information +# +# Table name: importers +# +# id :integer not null, primary key +# filename :string(64) default(""), not null +# md5sum :string(32) default(""), not null +# + +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') + +RSpec.describe Importer, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end From c70273d2dec26a7e9cfb4c8a3b6ae8b3e7b02f8d Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Mon, 25 Jan 2021 14:52:01 +0000 Subject: [PATCH 20/22] Remove useless ignored file --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 422fa5e2ca..6629b0283e 100644 --- a/.gitignore +++ b/.gitignore @@ -40,5 +40,4 @@ Design .vagrant docker-compose.override.yml -.bash_history .local/ From 063ac095eb8110085e2b8312075efe22f0fb12d6 Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Sat, 20 Feb 2021 04:09:36 -0500 Subject: [PATCH 21/22] Test importer --- spec/factories/importer.rb | 19 +++++++++++++++ spec/models/files/importer_spec.rb | 39 +++++++++++++++++++++++++++--- spec/spec_helper.rb | 2 ++ 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 spec/factories/importer.rb diff --git a/spec/factories/importer.rb b/spec/factories/importer.rb new file mode 100644 index 0000000000..723f11981f --- /dev/null +++ b/spec/factories/importer.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# Copyright (c) 2008-2013 Michael Dvorkin and contributors. +# +# Fat Free CRM is freely distributable under the terms of MIT license. +# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php +#------------------------------------------------------------------------------ +FactoryBot.define do + factory :importer do + entity_type { :lead } + entity_id { 1 } + attachment_file_size { Random::rand(1..1024) } + attachment_file_name { "#{FFaker::Filesystem::file_name}.#{%w[xls xlsx].sample}" } + attachment_content_type { %w[text/xml application/xml].sample } + status { FFaker::Lorem.word } + created_at { FactoryBot.generate(:time) } + updated_at { FactoryBot.generate(:time) } + end +end diff --git a/spec/models/files/importer_spec.rb b/spec/models/files/importer_spec.rb index 79d6ca96d6..0387c28f3f 100644 --- a/spec/models/files/importer_spec.rb +++ b/spec/models/files/importer_spec.rb @@ -9,13 +9,44 @@ # # Table name: importers # -# id :integer not null, primary key -# filename :string(64) default(""), not null -# md5sum :string(32) default(""), not null +# id :integer not null, primary key +# entity_type :string +# entity_id :integer +# attachment_file_size :integer +# attachment_file_name :string(255) +# attachment_content_type :string(255) +# status :string(255) +# created_at :datetime +# updated_at :datetime # require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') RSpec.describe Importer, type: :model do - pending "add some examples to (or delete) #{__FILE__}" + it "should create a new instance given valid attributes" do + Importer.create!(attributes_for(:importer)) + end + + describe "validates" do + it "attachment" do + is_expected.to have_attached_file(:attachment) + end + + it "attachment presence" do + is_expected.to validate_attachment_presence(:attachment) + end + + xit "attachment file size" do + is_expected.to validate_attachment_size(:attachment). + less_than(10.megabytes) + end + + it "attachment content type" do + is_expected.to validate_attachment_content_type(:attachment). + allowing('text/xml', 'application/xml', + 'application/vnd.ms-excel', 'application/x-ole-storage', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'). + rejecting('text/plain') + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a64548e48a..f68ec05477 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -12,6 +12,7 @@ require 'rspec/rails' require 'capybara/rails' require 'paper_trail/frameworks/rspec' +require "paperclip/matchers" require 'factory_bot_rails' require 'ffaker' @@ -47,6 +48,7 @@ config.include Warden::Test::Helpers config.include DeviseHelpers config.include FeatureHelpers + config.include Paperclip::Shoulda::Matchers Warden.test_mode! From 6c94c449e45e8cc7af8b2a0c435234c3b1307bb3 Mon Sep 17 00:00:00 2001 From: Luilver Garces Date: Sat, 20 Feb 2021 04:19:25 -0500 Subject: [PATCH 22/22] Fix offenses --- app/controllers/importers_controller.rb | 203 ++++++++++------------ app/models/files/imported_file.rb | 18 +- app/models/files/importer.rb | 12 +- app/views/importers/map_columns.html.haml | 2 +- config/initializers/file.rb | 12 +- config/initializers/paperclip.rb | 4 +- lib/fat_free_crm/import_handle.rb | 21 +-- spec/factories/importer.rb | 4 +- spec/models/files/importer_spec.rb | 14 +- 9 files changed, 144 insertions(+), 146 deletions(-) diff --git a/app/controllers/importers_controller.rb b/app/controllers/importers_controller.rb index a1edbdf153..feb4481771 100644 --- a/app/controllers/importers_controller.rb +++ b/app/controllers/importers_controller.rb @@ -14,9 +14,7 @@ class ImportersController < ApplicationController def new @importer = Importer.new @importer.entity_type = params[:entity_type] - if params[:entity_id] - @importer.entity_id = params[:entity_id] - end + @importer.entity_id = params[:entity_id] if params[:entity_id] respond_with(@importer) end @@ -35,12 +33,11 @@ def create respond_to do |format| if errors - format.html { render "create", :locals => {errors: errors} } + format.html { render "create", locals: { errors: errors } } else format.html { redirect_to form_map_columns_importer_path(@importer) } end end - end # get /importers/:id/map @@ -53,32 +50,28 @@ def form_map_columns attributes_extra = [] object = @importer.entity_class - _attrs = object.attribute_names - ['id'] + attrs = object.attribute_names - ['id'] - _attrs.each do |attr| + attrs.each do |attr| attributes.push( - { - name: attr, - required: object.validators_on(attr).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator } - } + name: attr, + required: object.validators_on(attr).any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator } ) end if @importer.entity_type == 'lead' - _attrs = Address.attribute_names - %w(id created_at updated_at deleted_at address_type addressable_type addressable_id) + attrs = Address.attribute_names - %w[id created_at updated_at deleted_at address_type addressable_type addressable_id] - _attrs.each do |attr| + attrs.each do |attr| attributes_extra.push( - { - name: attr, - required: Address.validators_on(attr).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator } - } + name: attr, + required: Address.validators_on(attr).any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator } ) end end respond_to do |format| - format.html { render "form_map_columns", :locals => {columns: columns, attributes: attributes, attributes_extra: attributes_extra} } + format.html { render "form_map_columns", locals: { columns: columns, attributes: attributes, attributes_extra: attributes_extra } } end end @@ -97,97 +90,93 @@ def map_columns end end -=begin - # get /campaigns/import AJAX - #---------------------------------------------------------------------------- - def import - @importer = Importer.new - @importer.entity_type = 'Campaign' - respond_with(@importer) - end - - # patch /campaigns/import AJAX - #---------------------------------------------------------------------------- - def import_upload - @error = false - @result = { - items: [], - errors: [] - } - - if params[:importer] - @importer = Importer.create(import_params) - if @importer.valid? - @importer.save - @result = FatFreeCRM::ImportHandle.process(@importer) - else - puts @importer.errors.full_messages - @result[:errors].push(@importer.errors.full_messages) - @error = true - end - end - respond_with(@error,@result) - end - - - # get /campaigns/%id/import AJAX - #---------------------------------------------------------------------------- - def import_leads - @importer = Importer.new - @importer.entity_type = 'Lead' - respond_with(@importer) - end - - # patch /campaigns/import AJAX - #---------------------------------------------------------------------------- - def uploads_import_leads - @error = false - @result = { - items: [], - errors: [] - } - - if params[:importer] - @importer = Importer.create(import_params) - if @importer.valid? - @importer.save - @colummns = FatFreeCRM::ImportHandle.get_columns(@importer.attachment.path) - else - puts @importer.errors.full_messages - @result[:errors].push(@importer.errors.full_messages) - @error = true - end - end - respond_with(@colummns) do |format| - format.js { render :uploads_import_leads } - end - end - -=end + # # get /campaigns/import AJAX + # #---------------------------------------------------------------------------- + # def import + # @importer = Importer.new + # @importer.entity_type = 'Campaign' + # respond_with(@importer) + # end + # + # # patch /campaigns/import AJAX + # #---------------------------------------------------------------------------- + # def import_upload + # @error = false + # @result = { + # items: [], + # errors: [] + # } + # + # if params[:importer] + # @importer = Importer.create(import_params) + # if @importer.valid? + # @importer.save + # @result = FatFreeCRM::ImportHandle.process(@importer) + # else + # puts @importer.errors.full_messages + # @result[:errors].push(@importer.errors.full_messages) + # @error = true + # end + # end + # respond_with(@error,@result) + # end + # + # + # # get /campaigns/%id/import AJAX + # #---------------------------------------------------------------------------- + # def import_leads + # @importer = Importer.new + # @importer.entity_type = 'Lead' + # respond_with(@importer) + # end + # + # # patch /campaigns/import AJAX + # #---------------------------------------------------------------------------- + # def uploads_import_leads + # @error = false + # @result = { + # items: [], + # errors: [] + # } + # + # if params[:importer] + # @importer = Importer.create(import_params) + # if @importer.valid? + # @importer.save + # @colummns = FatFreeCRM::ImportHandle.get_columns(@importer.attachment.path) + # else + # puts @importer.errors.full_messages + # @result[:errors].push(@importer.errors.full_messages) + # @error = true + # end + # end + # respond_with(@colummns) do |format| + # format.js { render :uploads_import_leads } + # end + # end + # # post /importers/create #---------------------------------------------------------------------------- -=begin - def create - @error = false - @result = { - items: [], - errors: [] - } - - if params[:importer] - @importer = Importer.create(import_params) - if @importer.valid? - @importer.save - @result = FatFreeCRM::ImportHandle.process(@importer) - else - puts @importer.errors.full_messages - @result[:errors].push(@importer.errors.full_messages) - @error = true - end - end - respond_with(@error,@result) - end -=end + # def create + # @error = false + # @result = { + # items: [], + # errors: [] + # } + # + # if params[:importer] + # @importer = Importer.create(import_params) + # if @importer.valid? + # @importer.save + # @result = FatFreeCRM::ImportHandle.process(@importer) + # else + # puts @importer.errors.full_messages + # @result[:errors].push(@importer.errors.full_messages) + # @error = true + # end + # end + # respond_with(@error,@result) + # end private diff --git a/app/models/files/imported_file.rb b/app/models/files/imported_file.rb index 9ac84c15ae..f0c019dd8e 100644 --- a/app/models/files/imported_file.rb +++ b/app/models/files/imported_file.rb @@ -24,19 +24,21 @@ class ImportedFile < ActiveRecord::Base validates :md5sum, uniqueness: { message: "file already imported" } def generate_md5sum - self.md5sum = Digest::MD5.hexdigest File.open(filename).read unless filename.empty? rescue "" + self.md5sum = Digest::MD5.hexdigest File.open(filename).read unless filename.empty? + rescue StandardError + "" end private def filetype - valid = File.open(filename).type_from_file_command == "application/vnd.ms-excel" rescue "" - if valid == "" - errors.add(:filename, "no such file") - end - unless valid - errors.add(:filename, "invalid filetype") - end + valid = begin + File.open(filename).type_from_file_command == "application/vnd.ms-excel" + rescue StandardError + "" + end + errors.add(:filename, "no such file") if valid == "" + errors.add(:filename, "invalid filetype") unless valid end ActiveSupport.run_load_hooks(:fat_free_crm_imported_file, self) diff --git a/app/models/files/importer.rb b/app/models/files/importer.rb index 1ad83c7185..1c04f94dea 100644 --- a/app/models/files/importer.rb +++ b/app/models/files/importer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # == Schema Information # # Table name: importers @@ -16,21 +18,21 @@ class Importer < ActiveRecord::Base attribute :entity_attrs - has_attached_file :attachment, :path => ":rails_root/public/importers/:id/:filename" + has_attached_file :attachment, path: ":rails_root/public/importers/:id/:filename" validates_attachment :attachment, presence: true validates_attachment_content_type :attachment, - :content_type => %w(text/xml application/xml application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/x-ole-storage), - :message => 'Only EXCEL files are allowed.' + content_type: %w[text/xml application/xml application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/x-ole-storage], + message: 'Only EXCEL files are allowed.' validates_attachment_file_name :attachment, matches: [/\.xls/, /\.xlsx?$/] - def get_messages() + def messages JSON.parse(messages) end def entity_class - self.entity_type.capitalize.constantize + entity_type.capitalize.constantize end ActiveSupport.run_load_hooks(:fat_free_crm_importer, self) diff --git a/app/views/importers/map_columns.html.haml b/app/views/importers/map_columns.html.haml index a7e3866cbe..78e1bc2c80 100644 --- a/app/views/importers/map_columns.html.haml +++ b/app/views/importers/map_columns.html.haml @@ -1,4 +1,4 @@ %div #{t :importer_status_label } #{ @importer.status } -- @importer.get_messages.each do |message| +- @importer.messages.each do |message| %div #{message} diff --git a/config/initializers/file.rb b/config/initializers/file.rb index c603f986af..05a84dd024 100644 --- a/config/initializers/file.rb +++ b/config/initializers/file.rb @@ -7,8 +7,16 @@ #------------------------------------------------------------------------------ File.class_eval do def type_from_file_command - type = (self.original_filename.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase - mime_type = `file -b --mime-type #{self.path}`.split(':').last.strip rescue "application/x-#{type}" + type = (begin + original_filename.match(/\.(\w+)$/)[1] + rescue StandardError + "octet-stream" + end).downcase + mime_type = begin + `file -b --mime-type #{path}`.split(':').last.strip + rescue StandardError + "application/x-#{type}" + end mime_type = "application/x-#{type}" if mime_type.match(/\(.*?\)/) mime_type end diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb index b85e39ae1a..e595b45f59 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + module Paperclip class MediaTypeSpoofDetector def spoofed? false end end -end \ No newline at end of file +end diff --git a/lib/fat_free_crm/import_handle.rb b/lib/fat_free_crm/import_handle.rb index 0cc76f5690..26b31170b9 100644 --- a/lib/fat_free_crm/import_handle.rb +++ b/lib/fat_free_crm/import_handle.rb @@ -11,14 +11,13 @@ module FatFreeCRM class ImportHandle class << self - def get_columns(path) - headers = Hash.new + headers = {} xlsx = Roo::Spreadsheet.open(path) sheet = xlsx.sheet(0) - sheet.row(1).each_with_index { |header, i| + sheet.row(1).each_with_index do |header, i| headers[header] = i - } + end headers end @@ -27,7 +26,7 @@ def get_values(map, sheet, row) map.each do |att, i| if i.is_a?(Hash) values[att] = get_values(i, sheet, row) - elsif not i.empty? and i.to_i >= 0 + elsif !i.empty? && (i.to_i >= 0) value = sheet.row(row)[i.to_i] values[att] = value end @@ -41,17 +40,15 @@ def process(importer) map = JSON.parse(importer.map) xlsx = Roo::Spreadsheet.open(importer.attachment.path) - xlsx.each_with_pagename do |name, sheet| + xlsx.each_with_pagename do |_name, sheet| ((sheet.first_row + 1)..sheet.last_row).each do |row| values = get_values(map, sheet, row) - # TODO Do this more geneic + # TODO: Do this more geneic business_address_attributes = {} if importer.entity_type == 'lead' values[:campaign_id] = importer.entity_id - if values.key?('business_address_attributes') - business_address_attributes = values.delete('business_address_attributes') - end + business_address_attributes = values.delete('business_address_attributes') if values.key?('business_address_attributes') end item = importer.entity_type.capitalize.constantize.create(values) @@ -70,7 +67,7 @@ def process(importer) end end - if errors.length == 0 + if errors.empty? importer.status = :imported else importer.status = :error @@ -83,5 +80,3 @@ def process(importer) end end end - - diff --git a/spec/factories/importer.rb b/spec/factories/importer.rb index 723f11981f..3623feeb8e 100644 --- a/spec/factories/importer.rb +++ b/spec/factories/importer.rb @@ -9,8 +9,8 @@ factory :importer do entity_type { :lead } entity_id { 1 } - attachment_file_size { Random::rand(1..1024) } - attachment_file_name { "#{FFaker::Filesystem::file_name}.#{%w[xls xlsx].sample}" } + attachment_file_size { Random.rand(1..1024) } + attachment_file_name { "#{FFaker::Filesystem.file_name}.#{%w[xls xlsx].sample}" } attachment_content_type { %w[text/xml application/xml].sample } status { FFaker::Lorem.word } created_at { FactoryBot.generate(:time) } diff --git a/spec/models/files/importer_spec.rb b/spec/models/files/importer_spec.rb index 0387c28f3f..c4c4333431 100644 --- a/spec/models/files/importer_spec.rb +++ b/spec/models/files/importer_spec.rb @@ -37,16 +37,16 @@ end xit "attachment file size" do - is_expected.to validate_attachment_size(:attachment). - less_than(10.megabytes) + is_expected.to validate_attachment_size(:attachment) + .less_than(10.megabytes) end it "attachment content type" do - is_expected.to validate_attachment_content_type(:attachment). - allowing('text/xml', 'application/xml', - 'application/vnd.ms-excel', 'application/x-ole-storage', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'). - rejecting('text/plain') + is_expected.to validate_attachment_content_type(:attachment) + .allowing('text/xml', 'application/xml', + 'application/vnd.ms-excel', 'application/x-ole-storage', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + .rejecting('text/plain') end end end