diff --git a/facebook_pixel_tracking/__init__.py b/facebook_pixel_tracking/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/facebook_pixel_tracking/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/facebook_pixel_tracking/__manifest__.py b/facebook_pixel_tracking/__manifest__.py new file mode 100644 index 00000000..30b876e0 --- /dev/null +++ b/facebook_pixel_tracking/__manifest__.py @@ -0,0 +1,41 @@ +############################################################################## +# +# Copyright (C) 2015 ADHOC SA (http://www.adhoc.com.ar) +# All Rights Reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + 'name': 'Facebook Pixel Tracking', + 'category': 'website', + 'version': "16.0.1.0.0", + 'author': 'ADHOC SA', + 'website': 'www.adhoc.com.ar', + 'license': 'AGPL-3', + 'depends': [ + 'website_sale_advanced_tracking', + ], + 'data': [ + 'views/res_config_settings_view.xml', + 'views/website_templates.xml', + ], + 'assets':{ + 'web.assets_frontend': [ + 'facebook_pixel_tracking/static/src/js/website_sale_tracking.js', + 'facebook_pixel_tracking/static/src/js/website_user_tracking.js' + ], + }, + 'installable': True, +} diff --git a/facebook_pixel_tracking/models/__init__.py b/facebook_pixel_tracking/models/__init__.py new file mode 100644 index 00000000..ba62e141 --- /dev/null +++ b/facebook_pixel_tracking/models/__init__.py @@ -0,0 +1,2 @@ +from . import res_config_settings +from . import website diff --git a/facebook_pixel_tracking/models/res_config_settings.py b/facebook_pixel_tracking/models/res_config_settings.py new file mode 100644 index 00000000..ac9a1a3d --- /dev/null +++ b/facebook_pixel_tracking/models/res_config_settings.py @@ -0,0 +1,9 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + facebook_pixel_key = fields.Char( + "Facebook pixel ID", related="website_id.facebook_pixel_key", readonly=False + ) diff --git a/facebook_pixel_tracking/models/website.py b/facebook_pixel_tracking/models/website.py new file mode 100644 index 00000000..d8e2ac48 --- /dev/null +++ b/facebook_pixel_tracking/models/website.py @@ -0,0 +1,7 @@ +from odoo import fields, models + + +class Website(models.Model): + _inherit = "website" + + facebook_pixel_key = fields.Char("Facebook pixel ID") diff --git a/facebook_pixel_tracking/static/src/js/website_sale_tracking.js b/facebook_pixel_tracking/static/src/js/website_sale_tracking.js new file mode 100644 index 00000000..2181217a --- /dev/null +++ b/facebook_pixel_tracking/static/src/js/website_sale_tracking.js @@ -0,0 +1,84 @@ +odoo.define("facebook_pixel_tracking.tracking", function (require) { + "use strict"; + + var publicWidget = require("web.public.widget"); + + const PaymentCheckoutForm = publicWidget.registry.PaymentCheckoutForm; + + publicWidget.registry.FacebookPixelTracking = publicWidget.Widget.extend({ + selector: '.oe_website_sale', + events: { + "click #add_to_cart": "_onClickAddToCartProduct", + "click a.add_to_cart_products_item": "_onClickAddToCartProductsItem", + "click a.on_checkout_start_js": "_onCheckoutStartJs", + }, + + _pushInfo: function (event, dict){ + if(typeof(fbq) !== 'undefined'){ + fbq('track', event, dict); + console.log(dict); + } + }, + _onClickAddToCartProduct: function (ev){ + var dataTarget = ev.target.closest('a#add_to_cart'); + var product_id = dataTarget.dataset.product_id; + var product_name = dataTarget.dataset.product_name; + var product_price = dataTarget.dataset.product_price; + var product_amount = $("[name=add_qty]").val(); + var amount = parseFloat(product_price * product_amount).toFixed(2); + const dict = { + 'content_name': product_name, + 'content_ids': [product_id], + 'content_type': 'product', + 'value': product_price, + 'total': amount, + } + this._pushInfo('AddToCart', dict); + }, + _onClickAddToCartProductsItem: function(ev) { + var dataTarget = ev.target.closest('div.o_wsale_product_btn'); + var product_id = dataTarget.dataset.product_id; + var product_sku = dataTarget.dataset.product_sku; + var product_name = dataTarget.dataset.product_name; + var product_price = dataTarget.dataset.product_price; + const dict = { + 'content_name': product_name, + 'content_ids': [product_sku || product_id], + 'content_type': 'product', + 'value': product_price, + } + this._pushInfo('AddToCart', dict); + }, + _onCheckoutStartJs: function () { + var dataTarget = $("#cart_products")[0]; + const info = dataTarget.dataset.cart_info; + const dict = { + 'event':'begin_checkout', + 'ecommerce':{'items':info} + } + this._pushInfo('OnCheckoutStart', dict); + }, + }); + + PaymentCheckoutForm.include({ + + _pushInfo: function (event, dict){ + if(typeof(fbq) !== 'undefined'){ + fbq('track', event, dict); + } + }, + + // @override + _onClickPay: async function (ev) { + const info = $(".toggle_summary_div")[0].dataset.purchase_info; + const dict = { + 'event':'purchase', + 'ecommerce':info + } + this._pushInfo('OnPurchaseConfirm', dict); + this._super(...arguments); + }, + }) + + return publicWidget.registry.FacebookPixelTracking; +}); diff --git a/facebook_pixel_tracking/static/src/js/website_user_tracking.js b/facebook_pixel_tracking/static/src/js/website_user_tracking.js new file mode 100644 index 00000000..bb570055 --- /dev/null +++ b/facebook_pixel_tracking/static/src/js/website_user_tracking.js @@ -0,0 +1,27 @@ +odoo.define("facebook_pixel_tracking.user_tracking", function (require) { + "use strict"; + + var publicWidget = require("web.public.widget"); + + publicWidget.registry.FacebookPixelTrackingUser = publicWidget.Widget.extend({ + selector: '.oe_website_login_container', + events: { + "click button.on_user_signup": "_onUserSignup", + }, + + _pushInfo: function (event, dict){ + if(typeof(fbq) !== 'undefined'){ + fbq('track', event, dict); + console.log(dict); + } + }, + _onUserSignup: function () { + const user_email = $("#login").val(); + const dict = { + 'user_email':user_email, + } + this._pushInfo('user_signup', dict); + }, + }); + return publicWidget.registry.FacebookPixelTrackingUser; +}); diff --git a/facebook_pixel_tracking/views/res_config_settings_view.xml b/facebook_pixel_tracking/views/res_config_settings_view.xml new file mode 100644 index 00000000..b7027185 --- /dev/null +++ b/facebook_pixel_tracking/views/res_config_settings_view.xml @@ -0,0 +1,52 @@ + + + + Facebook Pixel Tracking + res.config.settings + + +
+
+
+
+
+
+
+
+
diff --git a/facebook_pixel_tracking/views/website_templates.xml b/facebook_pixel_tracking/views/website_templates.xml new file mode 100644 index 00000000..737b92bf --- /dev/null +++ b/facebook_pixel_tracking/views/website_templates.xml @@ -0,0 +1,34 @@ + + + + diff --git a/website_sale_advanced_tracking/__init__.py b/website_sale_advanced_tracking/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/website_sale_advanced_tracking/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/website_sale_advanced_tracking/__manifest__.py b/website_sale_advanced_tracking/__manifest__.py new file mode 100644 index 00000000..72fa1604 --- /dev/null +++ b/website_sale_advanced_tracking/__manifest__.py @@ -0,0 +1,34 @@ +############################################################################## +# +# Copyright (C) 2015 ADHOC SA (http://www.adhoc.com.ar) +# All Rights Reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + 'name': 'Website Sale Advanced Tracking', + 'category': 'website', + 'version': "16.0.1.0.0", + 'author': 'ADHOC SA', + 'website': 'www.adhoc.com.ar', + 'license': 'AGPL-3', + 'depends': [ + 'website_sale', + ], + 'data': [ + 'views/templates.xml', + ], + 'installable': True, +} diff --git a/website_sale_advanced_tracking/models/__init__.py b/website_sale_advanced_tracking/models/__init__.py new file mode 100644 index 00000000..2d7ee6c3 --- /dev/null +++ b/website_sale_advanced_tracking/models/__init__.py @@ -0,0 +1,2 @@ +from . import sale_order +from . import sale_order_line diff --git a/website_sale_advanced_tracking/models/sale_order.py b/website_sale_advanced_tracking/models/sale_order.py new file mode 100644 index 00000000..0bfcba8e --- /dev/null +++ b/website_sale_advanced_tracking/models/sale_order.py @@ -0,0 +1,30 @@ +from odoo import models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + def prepare_purchase_information(self): + products = [] + for line in self.order_line: + products.append( + { + "id": line.product_id.default_code or line.product_id.id, + "name": line.product_id.name, + "category": line.product_id.categ_id.name, + "quantity": line.product_uom_qty, + "price": line.price_subtotal, + } + ) + res = { + 'purchase': { + 'actionField': { + 'id': self.id, + 'affiliation': self.partner_id.name, + 'revenue': self.amount_total, + 'tax':self.amount_tax, + }, + 'products': products + } + } + return res diff --git a/website_sale_advanced_tracking/models/sale_order_line.py b/website_sale_advanced_tracking/models/sale_order_line.py new file mode 100644 index 00000000..0b479d85 --- /dev/null +++ b/website_sale_advanced_tracking/models/sale_order_line.py @@ -0,0 +1,18 @@ +from odoo import models + + +class SaleOrderLine(models.Model): + _inherit = 'sale.order.line' + + def prepare_checkout_information(self): + res = [] + for line in self: + res.append( + { + 'item_name': line.name, + 'item_id': line.product_id.default_code or line.product_id.id, + 'price': (line.price_reduce_taxinc / line.product_uom_qty), + 'quantity': line.product_uom_qty + } + ) + return res diff --git a/website_sale_advanced_tracking/views/templates.xml b/website_sale_advanced_tracking/views/templates.xml new file mode 100644 index 00000000..bb0db242 --- /dev/null +++ b/website_sale_advanced_tracking/views/templates.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + +