2 var _gaq = _gaq || []; // asynchronous stack used by google analytics
4 openerp.web_analytics = function(instance) {
7 * The Web Analytics Module inserts the Google Analytics JS Snippet
8 * at the top of the page, and sends to google an url each time the
9 * openerp url is changed.
10 * The pushes of the urls is made by triggering the 'state_pushed' event in the
11 * web_client.do_push_state() method which is responsible of changing the openerp current url
14 // Google Analytics Code snippet
16 var ga = document.createElement('script');
17 ga.type = 'text/javascript';
19 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
20 var s = document.getElementsByTagName('script')[0];
21 s.parentNode.insertBefore(ga,s);
24 instance.web_analytics.Tracker = instance.web.Class.extend({
26 * This method initializes the tracker
29 /* Comment this lines when going on production, only used for testing on localhost
30 _gaq.push(['_setAccount', 'UA-35793871-1']);
31 _gaq.push(['_setDomainName', 'none']);
34 /* Uncomment this lines when going on production */
35 _gaq.push(['_setAccount', 'UA-7333765-1']);
36 _gaq.push(['_setDomainName', '.openerp.com']); // Allow multi-domain
40 * This method MUST be overriden by saas_demo and saas_trial in order to
41 * set the correct user type. By default, the user connected is local to the DB.
43 _get_user_type: function() {
47 * This method gets the user access level, to be used as CV in GA
49 _get_user_access_level: function() {
50 if (instance.session.uid === 1) {
52 // Make the difference between portal users and anonymous users
53 } else if (instance.session.username.indexOf('@') !== -1) {
54 if (instance.session.username.indexOf('anonymous') === -1) {
57 return 'Anonymous User';
59 } else if (instance.session.username.indexOf('anonymous') !== -1) {
60 return 'Anonymous User';
66 * This method contains the initialization of all user-related custom variables
67 * stored in GA. Also other modules can override it to add new custom variables
69 initialize_custom: function() {
70 // Track User Access Level, Custom Variable 4 in GA with visitor level scope
71 // Values: 'Admin User', 'Normal User', 'Portal User', 'Anonymous User'
72 _gaq.push(['_setCustomVar', 4, 'User Access Level', this.user_access_level, 1]);
74 // Track User Type Conversion, Custom Variable 3 in GA with session level scope
75 // Values: 'Visitor', 'Demo', 'Online Trial', 'Online Paying', 'Local User'
76 _gaq.push(['_setCustomVar', 1, 'User Type Conversion', this._get_user_type(), 2]);
78 return instance.session.rpc("/web/webclient/version_info", {})
80 _gaq.push(['_setCustomVar', 5, 'Version', res.server_version, 3]);
85 * This method contains the initialization of the object and view type
88 on_state_pushed: function(state) {
89 // Track only pages corresponding to a 'normal' view of OpenERP, views
90 // related to client actions are tracked by the action manager
91 if (state.model && state.view_type) {
93 var url = instance.web_analytics.generateUrl({'model': state.model, 'view_type': state.view_type});
95 'category': state.model,
96 'action': state.view_type,
102 * This method includes the tracker into views and managers. It can be overriden
103 * by other modules in order to extend tracking functionalities
105 include_tracker: function() {
107 // Track the events related with the creation and the modification of records,
108 // the view type is always form
109 instance.web.FormView.include({
110 init: function(parent, dataset, view_id, options) {
111 this._super.apply(this, arguments);
113 this.on('record_created', self, function(r) {
114 var url = instance.web_analytics.generateUrl({'model': r.model, 'view_type': 'form'});
121 this.on('record_saved', self, function(r) {
122 var url = instance.web_analytics.generateUrl({'model': r.model, 'view_type': 'form'});
132 // Track client actions
133 instance.web.ActionManager.include({
134 ir_actions_client: function (action, options) {
135 var url = instance.web_analytics.generateUrl({'action': action.tag});
136 var category = action.res_model || action.type;
138 'category': action.res_model || action.type,
139 'action': action.name || action.tag,
142 return this._super.apply(this, arguments);
146 // Track button events
147 instance.web.View.include({
148 do_execute_action: function(action_data, dataset, record_id, on_closed) {
149 var category = this.model || dataset.model || '';
151 if (action_data.name && _.isNaN(action_data.name-0)) {
152 action = action_data.name;
154 action = action_data.string || action_data.special || '';
156 var url = instance.web_analytics.generateUrl({'model': category, 'view_type': this.view_type});
158 'category': category,
162 return this._super.apply(this, arguments);
166 // Track error events
167 instance.web.CrashManager.include({
168 show_error: function(error) {
169 var hash = window.location.hash;
170 var params = $.deparam(hash.substr(hash.indexOf('#')+1));
172 if (params.model && params.view_type) {
173 options = {'model': params.model, 'view_type': params.view_type};
175 options = {'action': params.action};
177 var url = instance.web_analytics.generateUrl(options);
180 'category': error.message,
181 'action': error.data.fault_code,
183 'noninteraction': true,
187 'category': error.type,
188 'action': error.data.debug,
190 'noninteraction': true,
193 this._super.apply(this, arguments);
198 * Method called in order to send _trackEvent to GA
200 _push_event: function(options) {
201 _gaq.push(['_trackEvent',
206 options.noninteraction
210 * Method called in order to send ecommerce transactions to GA
212 _push_ecommerce: function(trans_data, item_list) {
213 _gaq.push(['_addTrans',
215 trans_data.store_name,
223 _.each(item_list, function(item) {
224 _gaq.push(['_addItem',
233 _gaq.push(['_trackTrans']);
237 // ----------------------------------------------------------------
239 // ----------------------------------------------------------------
241 instance.web_analytics.generateUrl = function(options) {
243 _.each(options, function(value, key) {
244 url += '/' + key + '=' + value;
249 instance.web_analytics.setupTracker = function(wc) {
251 return $.when(t._get_user_access_level()).then(function(r) {
252 t.user_access_level = r;
253 t.initialize_custom().then(function() {
254 wc.on('state_pushed', wc, t.on_state_pushed);
260 // Set correctly the tracker in the current instance
261 if (instance.client instanceof instance.web.WebClient) { // not for embedded clients
262 instance.webclient.tracker = new instance.web_analytics.Tracker();
263 instance.web_analytics.setupTracker(instance.webclient);
264 } else if (!instance.client) {
265 // client does not already exists, we are in monodb mode
266 instance.web.WebClient.include({
268 var d = this._super.apply(this, arguments);
269 this.tracker = new instance.web_analytics.Tracker();
272 show_application: function() {
274 instance.web_analytics.setupTracker(self).then(function() {