Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3 1 0 backport #36

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
source 'https://rubygems.org'

gem 'spree', github: 'spree/spree', branch: '3-0-stable'
gem 'spree_events_tracker', git: "https://github.com/vinsol/spree_events_tracker.git", branch: 'add-tracker'
gem 'spree', github: 'spree/spree', branch: 'master'
gem 'spree_events_tracker', git: "https://github.com/vinsol/spree_events_tracker.git", branch: 'master'

gemspec
64 changes: 46 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,53 @@
SpreeReportify
[SpreeAdminInsights](http://vinsol.com/spreecommerce-admin-insights)
==============

Introduction goes here.
When it comes to driving an Ecommerce business, knowing the right metrics and access to relevant data is half the battle won! This allows you to take immediate and more importantly, the right action.

This extension provides extensive and targeted reports for the Admin. Which products were viewed the most yesterday, which brand is most popular in a particular geography, which user is a consistent buyer and much more, all the reports a website owner could probably need are a click away!

Dependency
---------
you need to install [spree_events_tracker](https://github.com/vinsol-spree-contrib/spree_events_tracker) gem.

Features
--------
Elaborate reporting from the following categories are available:
* Financial Analysis - Involves reports around sales, payment methods and shipping etc
* Product Analysis - Insights of product purchase, abandoned cart etc
* Promotional analysis - Reports of promotional costs etc are available.
* Search Analysis - Search details reports.
* User Analysis - Includes elaborate user analysis.

**Other features include :**
* Search and Filter
* Save reports in various formats.
* Refresh reports
* Reset report
* Remove pagination or change pagination count.

Installation
------------

Add spree_reportify to your Gemfile:
1. Add spree_admin_insights to your Gemfile:

```ruby
gem 'spree_reportify'
```
```ruby
gem 'spree_admin_insights', git: 'https://github.com/vinsol-spree-contrib/spree-admin-insights'
```

Bundle your dependencies and run the installation generator:
2. Bundle your dependencies and run the installation generator:

```shell
bundle
bundle exec rails g spree_reportify:install
```
```shell
bundle
bundle exec rails g spree_admin_insights:install
```

3. Restart your server

Usage
-------
Once installed it will automatically starts all data loging and statistical analysis and provides you a user friendly graphical representation of reports. This extension also allows you to download the reports in multiple formats. For more detailed usage please see [this](http://vinsol.com/spreecommerce-admin-insights) blog.

To access these reports goto admin section and click on 'Insights' section in the vertical menu bar.

Testing
-------
Expand All @@ -26,14 +56,12 @@ First bundle your dependencies, then run `rake`. `rake` will default to building

```shell
bundle
bundle exec rake
bundle exec rspec spec
```

When testing your applications integration with this extension you may use it's factories.
Simply add this require statement to your spec_helper:
Credits
-------

```ruby
require 'spree_reportify/factories'
```
[![vinsol.com: Ruby on Rails, iOS and Android developers](http://vinsol.com/vin_logo.png "Ruby on Rails, iOS and Android developers")](http://vinsol.com)

Copyright (c) 2016 [name of extension creator], released under the New BSD License
Copyright (c) 2016 [vinsol.com](http://vinsol.com "Ruby on Rails, iOS and Android developers"), released under the New MIT License
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ end

desc 'Generates a dummy app for testing'
task :test_app do
ENV['LIB_NAME'] = 'spree_reportify'
ENV['LIB_NAME'] = 'spree_admin_insights'
Rake::Task['extension:test_app'].invoke
end
2 changes: 2 additions & 0 deletions app/assets/javascripts/spree/backend/spree_admin_insights.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//= require spree/backend/spree_admin_insights/report_loader
//= require spree/backend/tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Paginator.prototype.removePagination = function(currentElement) {
sorted_attributes = this.tableSorter.fetchSortedAttribute(),
attribute = sorted_attributes[0],
sortOrder = sorted_attributes[1],
requestUrl = $element.data('url') + '&sort%5Battribute%5D=' + attribute + '&sort%5Btype%5D=' + sortOrder + '&' + $('#filter-search').serialize() + '&no_pagination=true';
requestUrl = $element.data('url') + '&sort%5Battribute%5D=' + attribute + '&sort%5Btype%5D=' + sortOrder + '&' + $('#filter-search').serialize() + '&paginate=false';
$(currentElement).attr('href', requestUrl);
_this.reportLoader.requestUrl = requestUrl;
$element.val('');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//= require spree/backend/spree_reportify/paginator
//= require spree/backend/spree_reportify/searcher
//= require spree/backend/spree_reportify/table_sorter
//= require spree/backend/spree_admin_insights/paginator
//= require spree/backend/spree_admin_insights/searcher
//= require spree/backend/spree_admin_insights/table_sorter

function ReportLoader(inputs) {
this.$selectList = inputs.reportsSelectBox;
Expand Down Expand Up @@ -83,9 +83,9 @@ ReportLoader.prototype.bindEvents = function() {
ReportLoader.prototype.resetFilters = function(event) {
event.preventDefault();
var $element = $(event.target),
noPagination = this.removePaginationButton.closest('span').hasClass('hide');
$element.attr('href', this.perPageSelector.data('url') + '&no_pagination=' + noPagination);
$element.data('url', this.perPageSelector.data('url') + '&no_pagination=' + noPagination);
paginated = !this.removePaginationButton.closest('span').hasClass('hide');
$element.attr('href', this.perPageSelector.data('url') + '&paginate=' + paginated);
$element.data('url', this.perPageSelector.data('url') + '&paginate=' + paginated);
this.loadChart($element);
this.searcherObject.clearSearchFields();
};
Expand Down Expand Up @@ -136,7 +136,7 @@ ReportLoader.prototype.fetchChartData = function(url, $selectedOption) {
$(object).removeClass('col-md-3').addClass('col-md-2');
});
}
_this.perPageSelector.data('url', data['request_path'] + '?type=' + data['report_type']);
_this.perPageSelector.data('url', data['request_path'] + '?report_category=' + data['report_category']);
_this.setDownloadLinksPath();
_this.searcherObject.refreshSearcher($selectedOption, data);
_this.paginatorObject.refreshPaginator(data);
Expand Down Expand Up @@ -187,7 +187,7 @@ ReportLoader.prototype.populateInsightsData = function(data) {
ReportLoader.prototype.setDownloadLinksPath = function($selectedOption) {
var _this = this;
$.each(this.downloadLinks, function() {
$(this).attr('href', $(this).data('url') + '?id=' + _this.$selectList.val() + '&no_pagination=true');
$(this).attr('href', $(this).data('url') + '?id=' + _this.$selectList.val() + '&paginate=false');
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//= require spree/backend/spree_reportify/paginator
//= require spree/backend/spree_admin_insights/paginator

function Searcher(inputs, reportLoader) {
this.$insightsTableList = inputs.insightsDiv;
Expand Down Expand Up @@ -28,12 +28,12 @@ Searcher.prototype.refreshSearcher = function($selectedInsight, data) {
_this.setFormActions(_this.$filterForm, requestPath);

_this.$filterForm.on('submit', function() {
var noPagination = _this.reportLoader.removePaginationButton.closest('span').hasClass('hide');
var paginated = !_this.reportLoader.removePaginationButton.closest('span').hasClass('hide');
_this.addSearchStatus();
$.ajax({
type: "GET",
url: _this.$filterForm.attr('action'),
data: _this.$filterForm.serialize() + "&per_page=" + _this.reportLoader.pageSelector.find(':selected').attr('value') + '&no_pagination=' + noPagination,
data: _this.$filterForm.serialize() + "&per_page=" + _this.reportLoader.pageSelector.find(':selected').attr('value') + '&paginate=' + paginated,
dataType: 'json',
success: function(data) {
_this.clearFormFields();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ TableSorter.prototype.bindEvents = function() {
this.$insightsTableList.on('click', '#admin-insight .sortable-link', function() {
event.preventDefault();
var currentPage = _this.paginatorDiv.find('li.active a').html() - 1,
noPagination = _this.reportLoader.removePaginationButton.closest('span').hasClass('hide'),
requestPath = $(event.target).attr('href') + '&' + $('#filter-search').serialize() + '&page=' + currentPage + "&per_page=" + _this.reportLoader.pageSelector.find(':selected').attr('value') + '&no_pagination=' + noPagination;
paginated = !_this.reportLoader.removePaginationButton.closest('span').hasClass('hide'),
requestPath = $(event.target).attr('href') + '&' + $('#filter-search').serialize() + '&page=' + currentPage + "&per_page=" + _this.reportLoader.pageSelector.find(':selected').attr('value') + '&paginate=' + paginated;
_this.reportLoader.requestUrl = requestPath;

$.ajax({
Expand Down
2 changes: 0 additions & 2 deletions app/assets/javascripts/spree/backend/spree_reportify.js

This file was deleted.

83 changes: 50 additions & 33 deletions app/controllers/spree/admin/insights_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Spree
module Admin
class InsightsController < Spree::Admin::BaseController
before_action :ensure_report_exists, :set_default_pagination, only: [:show, :download]
before_action :set_reporting_period, only: [:index, :show, :download]
before_action :load_reports, only: [:index, :show]

def index
Expand All @@ -12,46 +13,29 @@ def index
end

def show
@headers, @stats, @total_pages, @search_attributes, @chart_json, @resource = ReportGenerationService.generate_report(
@report_name,
params.merge(@pagination_hash)
)

@report_data_json = {
current_page: params[:page] || 0,
headers: @headers,
report_type: params[:type],
request_path: request.path,
search_attributes: @search_attributes,
stats: @stats,
total_pages: @total_pages,
url: request.url,
searched_fields: params[:search],
per_page: @pagination_hash[:records_per_page],
chart_json: @chart_json,
pagination_required: [email protected]_pagination?
}
report = ReportGenerationService.generate_report(@report_name, params.merge(@pagination_hash))

@report_data = shared_data.merge(report.to_h)
respond_to do |format|
format.html { render :index }
format.json { render json: @report_data_json }
format.json { render json: @report_data }
end
end

def download
@headers, @stats = ReportGenerationService.generate_report(@report_name, params.merge(@pagination_hash))
@report = ReportGenerationService.generate_report(@report_name, params.merge(@pagination_hash))

respond_to do |format|
format.csv do
send_data ReportGenerationService.download(@headers, @stats),
send_data ReportGenerationService.download(@report),
filename: "#{ @report_name.to_s }.csv"
end
format.xls do
send_data ReportGenerationService.download({ col_sep: "\t" }, @headers, @stats),
send_data ReportGenerationService.download(@report, { col_sep: "\t" }),
filename: "#{ @report_name.to_s }.xls"
end
format.text do
send_data ReportGenerationService.download(@headers, @stats),
send_data ReportGenerationService.download(@report),
filename: "#{ @report_name.to_s }.txt"
end
format.pdf do
Expand All @@ -65,27 +49,60 @@ def download
private
def ensure_report_exists
@report_name = params[:id].to_sym
unless ReportGenerationService::REPORTS[get_reports_type].include? @report_name
unless ReportGenerationService.report_exists?(get_report_category, @report_name)
redirect_to admin_insights_path, alert: Spree.t(:not_found, scope: [:reports])
end
end

def load_reports
@reports = ReportGenerationService::REPORTS[get_reports_type]
@reports = ReportGenerationService.reports_for_category(get_report_category)
end

def shared_data
{
current_page: params[:page] || 0,
report_category: params[:report_category],
request_path: request.path,
url: request.url,
searched_fields: params[:search],
}
end

def get_report_category
params[:report_category] = if params[:report_category]
params[:report_category].to_sym
else
session[:report_category].try(:to_sym) || ReportGenerationService.default_report_category
end
session[:report_category] = params[:report_category]
end

def get_reports_type
params[:type] = if params[:type]
params[:type].to_sym
def set_reporting_period
if params[:search].present?
if params[:search][:start_date] == ""
# When clicking on 'x' to remove the filter
params[:search][:start_date] = nil
else
params[:search][:start_date] = params[:search][:start_date] || session[:search_start_date]
end
if params[:search][:end_date] == ""
params[:search][:end_date] = nil
else
params[:search][:end_date] = params[:search][:end_date].presence || session[:search_end_date]
end
else
session[:report_category].try(:to_sym) || ReportGenerationService::REPORTS.keys.first
params[:search] = {}
params[:search][:start_date] = session[:search_start_date]
params[:search][:end_date] = session[:search_end_date]
end
session[:report_category] = params[:type]
session[:search_start_date] = params[:search][:start_date]
session[:search_end_date] = params[:search][:end_date]
end

def set_default_pagination
@pagination_hash = {}
if params[:no_pagination] != 'true'
@pagination_hash = { paginate: false }
unless params[:paginate] == 'false'
@pagination_hash[:paginate] = true
@pagination_hash[:records_per_page] = params[:per_page].try(:to_i) || Spree::Config[:records_per_page]
@pagination_hash[:offset] = params[:page].to_i * @pagination_hash[:records_per_page]
end
Expand Down
3 changes: 3 additions & 0 deletions app/models/spree/product_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Spree::Product.class_eval do
has_many :page_view_events, -> { viewed.product }, class_name: 'Spree::PageEvent', foreign_key: :target_id
end
3 changes: 3 additions & 0 deletions app/models/spree/promotion_action_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Spree::PromotionAction.class_eval do
has_one :adjustment, -> { promotion }, class_name: 'Spree::Adjustment', foreign_key: :source_id
end
4 changes: 4 additions & 0 deletions app/models/spree/return_authorization_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Spree::ReturnAuthorization.class_eval do
has_many :variants, through: :inventory_units
has_many :products, through: :variants
end
3 changes: 3 additions & 0 deletions app/models/spree/user_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Spree::User.class_eval do
has_many :spree_orders, class_name: 'Spree::Order'
end
58 changes: 0 additions & 58 deletions app/reports/spree/annual_promotional_cost_report.rb

This file was deleted.

Loading