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 * Method called in order to send _trackEvent to GA
87 _push_event: function(options) {
88 _gaq.push(['_trackEvent',
93 options.noninteraction
97 * Method called in order to send ecommerce transactions to GA
99 _push_ecommerce: function(trans_data, item_list) {
100 _gaq.push(['_addTrans',
102 trans_data.store_name,
110 _.each(item_list, function(item) {
111 _gaq.push(['_addItem',
120 _gaq.push(['_trackTrans']);
123 * This method contains the initialization of the object and view type
126 on_state_pushed: function(state) {
127 // Track only pages corresponding to a 'normal' view of OpenERP, views
128 // related to client actions are tracked by the action manager
129 if (state.model && state.view_type) {
131 var url = instance.web_analytics.generateUrl({'model': state.model, 'view_type': state.view_type});
133 'category': state.model,
134 'action': state.view_type,
140 * This method includes the tracker into views and managers. It can be overriden
141 * by other modules in order to extend tracking functionalities
143 include_tracker: function() {
145 // Track the events related with the creation and the modification of records,
146 // the view type is always form
147 instance.web.FormView.include({
148 init: function(parent, dataset, view_id, options) {
149 this._super.apply(this, arguments);
151 this.on('record_created', self, function(r) {
152 var url = instance.web_analytics.generateUrl({'model': r.model, 'view_type': 'form'});
159 this.on('record_saved', self, function(r) {
160 var url = instance.web_analytics.generateUrl({'model': r.model, 'view_type': 'form'});
170 // Track client actions
171 instance.web.ActionManager.include({
172 ir_actions_client: function (action, options) {
173 var url = instance.web_analytics.generateUrl({'action': action.tag});
174 var category = action.res_model || action.type;
176 'category': action.res_model || action.type,
177 'action': action.name || action.tag,
180 return this._super.apply(this, arguments);
184 // Track button events
185 instance.web.View.include({
186 do_execute_action: function(action_data, dataset, record_id, on_closed) {
187 var category = this.model || dataset.model || '';
189 if (action_data.name && _.isNaN(action_data.name-0)) {
190 action = action_data.name;
192 action = action_data.string || action_data.special || '';
194 var url = instance.web_analytics.generateUrl({'model': category, 'view_type': this.view_type});
196 'category': category,
200 return this._super.apply(this, arguments);
204 // Track error events
205 instance.web.CrashManager.include({
206 show_error: function(error) {
207 var hash = window.location.hash;
208 var params = $.deparam(hash.substr(hash.indexOf('#')+1));
210 if (params.model && params.view_type) {
211 options = {'model': params.model, 'view_type': params.view_type};
213 options = {'action': params.action};
215 var url = instance.web_analytics.generateUrl(options);
218 'category': error.message,
219 'action': error.data.fault_code,
221 'noninteraction': true,
225 'category': error.type,
226 'action': error.data.debug,
228 'noninteraction': true,
231 this._super.apply(this, arguments);
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', t, 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).always(function() {