diff --git a/app/assets/javascripts/spree/backend/csv_input_button.js b/app/assets/javascripts/spree/backend/csv_input_button.js
new file mode 100644
index 0000000..247fa12
--- /dev/null
+++ b/app/assets/javascripts/spree/backend/csv_input_button.js
@@ -0,0 +1,28 @@
+function CsvInputButton(input) {
+ this.fileInput = input.fileInput;
+ this.submitButton = input.submitButton;
+ this.form = input.form;
+}
+ CsvInputButton.prototype.init = function() {
+ var _this = this;
+ this.submitButton.on('click', function() {
+ event.preventDefault();
+ _this.fileInput.click();
+ _this.submitForm();
+ });
+};
+ CsvInputButton.prototype.submitForm = function() {
+ var _this = this;
+ this.fileInput.on('change', function() {
+ _this.form.submit();
+ });
+};
+ $(function() {
+ var inputs = {
+ fileInput: $('input#file'),
+ submitButton: $('input[data-disable-with="Import Store Credit CSV"]'),
+ form: $("form[data-hook='csv_form']")
+ },
+ csvButtonsManager = new CsvInputButton(inputs);
+ csvButtonsManager.init();
+});
diff --git a/app/assets/javascripts/spree/backend/spree_bulk_store_credits.js b/app/assets/javascripts/spree/backend/spree_bulk_store_credits.js
index 8aa3b01..f246b20 100644
--- a/app/assets/javascripts/spree/backend/spree_bulk_store_credits.js
+++ b/app/assets/javascripts/spree/backend/spree_bulk_store_credits.js
@@ -1,2 +1,3 @@
// Placeholder manifest file.
-// the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
\ No newline at end of file
+// the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
+//= require spree/backend/csv_input_button
diff --git a/app/assets/stylesheets/spree/backend/spree_bulk_store_credits.css b/app/assets/stylesheets/spree/backend/spree_bulk_store_credits.css
index e3c2366..987bc6f 100644
--- a/app/assets/stylesheets/spree/backend/spree_bulk_store_credits.css
+++ b/app/assets/stylesheets/spree/backend/spree_bulk_store_credits.css
@@ -2,3 +2,10 @@
Placeholder manifest file.
the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
*/
+input.file-browse {
+ display: none;
+}
+
+ a.sample-download {
+ padding-right: 13px;
+}
diff --git a/app/controllers/spree/admin/users_controller_decorator.rb b/app/controllers/spree/admin/users_controller_decorator.rb
new file mode 100644
index 0000000..e1c32f8
--- /dev/null
+++ b/app/controllers/spree/admin/users_controller_decorator.rb
@@ -0,0 +1,22 @@
+Spree::Admin::UsersController.class_eval do
+ def sample_store_credit_csv
+ send_file STORE_CREDIT_CSV_FILE[:sample_store_credit_file]
+ end
+
+ def import_store_credits
+ begin
+ create_store_credit_updater
+ redirect_to admin_users_path, notice: Spree.t(:email_sent, filename: @store_credit_updater.data_file_file_name)
+ rescue
+ redirect_to admin_users_path, notice: "Invalid CSV file format."
+ end
+ end
+
+ private
+
+ def create_store_credit_updater
+ @store_credit_updater = Spree::BulkStoreCreditUpdater.create(data_file: params[:file])
+ NotifyStoreCreditService.delay(run_at: 1.minutes.from_now).new(@store_credit_updater.id, try_spree_current_user.email)
+ end
+
+end
diff --git a/app/mailers/spree/store_credit_updater_mailer.rb b/app/mailers/spree/store_credit_updater_mailer.rb
new file mode 100644
index 0000000..5dee1f8
--- /dev/null
+++ b/app/mailers/spree/store_credit_updater_mailer.rb
@@ -0,0 +1,11 @@
+module Spree
+ class StoreCreditUpdaterMailer < BaseMailer
+ def update_admin(status_csv, admin_email, filename, total_records, successfull_records)
+ @total_records = total_records
+ @failed_records = total_records - successfull_records
+ attachments['stock_items.csv'] = status_csv
+ subject = "#{Spree::Store.current.name} import of #{ filename } has finished"
+ mail(to: admin_email, from: from_address, subject: subject)
+ end
+ end
+end
diff --git a/app/models/spree/bulk_store_credit_updater.rb b/app/models/spree/bulk_store_credit_updater.rb
new file mode 100644
index 0000000..bb83aed
--- /dev/null
+++ b/app/models/spree/bulk_store_credit_updater.rb
@@ -0,0 +1,6 @@
+module Spree
+ class BulkStoreCreditUpdater < Spree::Base
+ has_attached_file :data_file
+ validates_attachment :data_file, content_type: { content_type: ["text/csv", "text/plain"] }
+ end
+end
diff --git a/app/overrides/add_import_button_on_user_index_page.rb b/app/overrides/add_import_button_on_user_index_page.rb
new file mode 100644
index 0000000..7b6d38d
--- /dev/null
+++ b/app/overrides/add_import_button_on_user_index_page.rb
@@ -0,0 +1,6 @@
+Deface::Override.new(
+ virtual_path: 'spree/admin/shared/_content_header',
+ name: 'add_import_button_on_user_index_page',
+ insert_bottom: "div[data-hook='toolbar']",
+ partial: 'spree/admin/users/import_button'
+)
diff --git a/app/services/notify_store_credit_service.rb b/app/services/notify_store_credit_service.rb
new file mode 100644
index 0000000..a8f57c5
--- /dev/null
+++ b/app/services/notify_store_credit_service.rb
@@ -0,0 +1,66 @@
+require 'csv'
+ class NotifyStoreCreditService
+ CSV_HEADERS = { 'Email': :Email, 'Store_Credit': :Store_Credit, 'Memo': :Memo, 'Category_ID': :Category_ID, 'Status': :Status }
+
+ def initialize(store_credit_updater_id, admin_email)
+ @store_credit_updater = Spree::BulkStoreCreditUpdater.find_by(id: store_credit_updater_id)
+ update_store_credits
+ @store_credit_updater.update_column(:job_executed, true)
+ Spree::StoreCreditUpdaterMailer.update_admin(@csv_export, admin_email, @store_credit_updater.data_file_file_name, @total_records, @successfull_records).deliver_now
+ @store_credit_updater.destroy if @store_credit_updater.job_executed?
+ end
+
+ private
+ def update_store_credits
+ @total_records = 0
+ @successfull_records = 0
+ @csv_export = CSV.generate do |csv|
+ unless csv_empty?
+ csv << CSV_HEADERS.keys
+ CSV.foreach(@store_credit_updater.data_file.path, headers: true) do |row|
+ @error = nil
+ @total_records += 1
+ @row = row
+ @user = find_user
+ if @user
+ update_stocks_with_csv_values
+ else
+ @error = Spree.t(:user_not_found)
+ end
+ csv << set_row
+ end
+ end
+ end
+ end
+
+ def csv_empty?
+ CSV.readlines(@store_credit_updater.data_file.path) == [[]]
+ end
+
+ def set_row
+ row = []
+ CSV_HEADERS.each do |key, value|
+ row << create_csv_row(key, value)
+ end
+ row
+ end
+
+ def create_csv_row(key, value)
+ ( key == :Status ) ? error_message : @row[value.to_s]
+ end
+
+ def error_message
+ @error ? @error : 'Successfully Updated'
+ end
+
+ def update_stocks_with_csv_values
+ admin = Spree::User.admin.first
+ store_credit = Spree::StoreCredit.new(amount: @row['Store_Credit'].to_f, created_by_id: admin.id, currency: "USD", category_id: @row['Category_ID'], memo: @row['Memo'])
+ @user.store_credits << store_credit
+ @successfull_records += 1
+ end
+
+ def find_user
+ Spree::User.find_by_email(@row['Email'])
+ end
+end
diff --git a/app/views/spree/admin/users/_import_button.html.erb b/app/views/spree/admin/users/_import_button.html.erb
new file mode 100644
index 0000000..0ead1a0
--- /dev/null
+++ b/app/views/spree/admin/users/_import_button.html.erb
@@ -0,0 +1,7 @@
+<% if request.path == admin_users_path %>
+ <%= form_tag import_store_credits_admin_users_path, multipart: true, class: 'form-inline', data: { hook: "csv_form" } do %>
+ <%= file_field_tag :file, class: 'file-browse' %>
+ <%= submit_tag Spree.t(:import), class: 'btn-success btn' %>
+ <%= link_to Spree.t(:example) , sample_store_credit_csv_admin_users_path, class: 'sample-download' %>
+ <% end %>
+<% end %>
diff --git a/app/views/spree/shared/_base_mailer_header.html.erb b/app/views/spree/shared/_base_mailer_header.html.erb
new file mode 100644
index 0000000..b2dbe49
--- /dev/null
+++ b/app/views/spree/shared/_base_mailer_header.html.erb
@@ -0,0 +1,33 @@
+
+
diff --git a/app/views/spree/store_credit_updater_mailer/update_admin.html.erb b/app/views/spree/store_credit_updater_mailer/update_admin.html.erb
new file mode 100644
index 0000000..adc3287
--- /dev/null
+++ b/app/views/spree/store_credit_updater_mailer/update_admin.html.erb
@@ -0,0 +1,8 @@
+
+
<%= Spree.t(:update_status) %>
+
+ - Number of records imported : <%= @total_records %>
+ - Number of records failed : <%= @failed_records %>
+
+
Attached is a csv file of failed records for your information.
+
diff --git a/config/initializers/spree_bulk_store_credits_constants.rb b/config/initializers/spree_bulk_store_credits_constants.rb
new file mode 100644
index 0000000..4caab20
--- /dev/null
+++ b/config/initializers/spree_bulk_store_credits_constants.rb
@@ -0,0 +1,3 @@
+STORE_CREDIT_CSV_FILE = {
+ sample_store_credit_file: SpreeBulkStoreCredits::Engine.root.join('lib', 'sample_csv', 'bulk_store_credits_example.csv')
+}
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 179c14c..4cd47bb 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -2,4 +2,8 @@
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
- hello: "Hello world"
+ spree:
+ import: Import Store Credit CSV
+ example: Download Sample File
+ email_sent: "%{filename} has been successfully imported. Details will be sent shortly to you over an email."
+ user_not_found: User with this email Not found
diff --git a/config/routes.rb b/config/routes.rb
index 0339717..aafaaa2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,3 +1,9 @@
Spree::Core::Engine.add_routes do
# Add your extension routes here
+ namespace :admin, path: Spree.admin_path do
+ resources :users do
+ collection { post :import_store_credits }
+ collection { get :sample_store_credit_csv }
+ end
+ end
end
diff --git a/db/migrate/20180806080802_create_spree_bulk_store_credit_updater.rb b/db/migrate/20180806080802_create_spree_bulk_store_credit_updater.rb
new file mode 100644
index 0000000..dfd6f37
--- /dev/null
+++ b/db/migrate/20180806080802_create_spree_bulk_store_credit_updater.rb
@@ -0,0 +1,8 @@
+class CreateSpreeBulkStoreCreditUpdater < ActiveRecord::Migration[4.2]
+ def change
+ create_table :spree_bulk_store_credit_updaters do |t|
+ t.boolean :job_executed, default: false
+ t.attachment :data_file
+ end
+ end
+end
diff --git a/lib/sample_csv/bulk_store_credits_example.csv b/lib/sample_csv/bulk_store_credits_example.csv
new file mode 100644
index 0000000..afec6b7
--- /dev/null
+++ b/lib/sample_csv/bulk_store_credits_example.csv
@@ -0,0 +1,2 @@
+Email,Store Credit,Memo,Category ID
+spree@example.com,10,Order benefit,1