vinsol-spree-contrib / spree-admin-insights

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!
http://vinsol.com/spreecommerce-admin-insights
BSD 3-Clause "New" or "Revised" License
20 stars 63 forks source link

More flexible reporting #33

Closed nimish-mehta closed 7 years ago

nimish-mehta commented 7 years ago

This PR ports over the changes we are making to admin insights for solidus over to spree.

Functional Changes

  1. Removal of Dependency on Sequel Gem. All reports are now built in Arel. This also removes most of the inconsistencies we had with certain features not working for Postgres. All reports are now database agnostic.

  2. Move over some calculations into ruby code. Features like Round give different results in Postgres and MySQL. they are moved over to ruby for more consistency.

  3. Move over some formatting concerns like Month name to ruby code. This allows us to time scale easily as well as open way for db agnostic localisations later.

  4. Automatic Time scaling of Reports. Earlier the time bound reports were restricted to a Monthly view. Now depending on the reporting interval the result changes to a more appropriate interval. i.e.

    • Same Day => Hourly Report
    • Less Than 60 Days => Daily Report
    • Between 60 Days and 600 Days => Monthly Report
    • Else => Yearly Report

    This reporting period is mantained in session and carried over to all reports which support it to make jumping between multiple reports easier.

  5. Deeplink support in reports. Now report results can link to items being reported. i.e product link in product reports or search link in search reports.

  6. Configuration moved to initializer, now list of reports can be configured from the initializer instead of opening ReportGenerationService class

Architectural Changes

The code has been significantly refactored and introduces following abstractions to build new reports:

Each report inherits from Spree::Report and defines a report_query method. If the report is to be paginated. it should define a method called paginated and set it to return true alongwith defining paginated_report_query and record_count_query. *_query methods should return objects that respond to to_sql which returns sql for reporting query.

Additionally all reports need to define two nested classes. Result and Result::Observation.

Result class can inherit from Spree::Report::Result if it is a basic report or from Spree::Report::TimedResult if the result can be time scaled.

Similarly Observation class needs to inherit either from Spree::Report::Observation or Spree::Report::TimedObservation. It has a macro call observation_fields which can be passed an array or hash with default values of fields which form one report item. Create a method of same name in Observation class for virtual fields. ie. average or for formatting db results.

The TimedResult has 2 lifecycle methods which can be overriden for customizing the report output.

  1. build_empty_observations
  2. populate_observations

Similarly TimedObservation defines a describes? method which can be overriden to change where the query results gets copied to.

The Result class can also add charts via a macro call to charts. The chart gets the results and need to implement to_h method returning the representation of chart.

The final json output of the report consists of metadata and charts from result & collection of observations.