Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
116 changes: 116 additions & 0 deletions facebook_pixel_tracking/static/src/js/website_sale_tracking.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<<<<<<< HEAD
||||||| MERGE BASE
=======
/** @odoo-module **/

import publicWidget from "@web/legacy/js/public/public_widget";


const PaymentForm = publicWidget.registry.PaymentForm;

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(event,dict);
},

_onClickAddToCartProduct: function (ev) {
var dataTarget = ev.target.closest('a#add_to_cart');
var product_id = dataTarget.dataset.product_id;
var product_sku = dataTarget.dataset.product_sku;
var product_name = dataTarget.dataset.product_name;
var product_price = parseFloat(dataTarget.dataset.product_price) || 0;
var currency = dataTarget.dataset.currency;
const dict = {
content_name: product_name,
content_ids: [String(product_sku || product_id)],
content_type: 'product',
value: product_price,
currency: currency,
};
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 = parseFloat(dataTarget.dataset.product_price) || 0;
const dict = {
content_name: product_name,
content_ids: [String(product_sku || product_id)],
content_type: 'product',
value: product_price,
};
this._pushInfo('AddToCart', dict);
},

_onCheckoutStartJs: function () {
var dataTarget = $("#cart_products")[0];
const items = JSON.parse(dataTarget.dataset.cart_info || '[]');
const contents = items
.filter(item => !item.is_reward_line)
.map(item => ({
id: String(item.item_id),
quantity: item.quantity,
item_price: item.price,
}));
if (!contents.length) {
return;
}
const dict = {
content_ids: contents.map(item => item.id),
content_type: 'product',
contents: contents,
num_items: contents.length,
value: parseFloat(dataTarget.dataset.value) || 0,
currency: dataTarget.dataset.currency,
};
this._pushInfo('InitiateCheckout', dict);
},
});

// Heredamos PaymentForm porque el método _submitForm tiene stopPropagation y preventDefault,
// impidiéndonos capturarlo desde el widget FacebookPixelTracking.
PaymentForm.include({

_pushInfo: function (event, dict) {
if (typeof fbq !== 'undefined') {
fbq('track', event, dict);
}
},

// @override
_submitForm: async function (ev) {
const info_div = $("#o_wsale_accordion_item")[0];
if (info_div) {
const info = JSON.parse(info_div.dataset.purchase_info || '{}');
const contents = (info.items || []).map(item => ({
id: String(item.item_id),
quantity: item.quantity,
item_price: item.price,
}));
const dict = {
value: info.value,
currency: info.currency,
content_ids: contents.map(item => item.id),
contents: contents,
content_type: 'product',
};
this._pushInfo('Purchase', dict);
}
await this._super(...arguments);
},
})

>>>>>>> FORWARD PORTED
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export class GoogleTagManagerAdvancedTracking extends Interaction {
dataLayer.push(dict);
console.log(dict);
}
<<<<<<< e9aa8e7dd3e7f495758de7710f7b5500db4fb4ca:google_tag_manager_advanced_tracking/static/src/interactions/website_sale_tracking.js
}

onClickAddToCartProduct(ev) {
Expand All @@ -54,14 +55,36 @@ export class GoogleTagManagerAdvancedTracking extends Interaction {
const product_price = dataTarget.dataset.product_price;
const product_amount = document.querySelector("[name=add_qty]").value;
const amount = parseFloat(product_price * product_amount).toFixed(2);
||||||| 3f4ea8024a54c6554045e9b425387a4c0a8d2755:google_tag_manager_advanced_tracking/static/src/js/website_sale_tracking.js
},
_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 currency = dataTarget.dataset.currency;
var product_price = dataTarget.dataset.product_price;
var product_amount = $("[name=add_qty]").val();
var amount = parseFloat(product_price * product_amount).toFixed(2);
=======
},
_onClickAddToCartProduct: function (ev) {
var dataTarget = ev.target.closest('a#add_to_cart');
var product_id = dataTarget.dataset.product_id;
var product_sku = dataTarget.dataset.product_sku;
var product_name = dataTarget.dataset.product_name;
var currency = dataTarget.dataset.currency;
var product_price = dataTarget.dataset.product_price;
var product_amount = $('[name=add_qty]').val();
var amount = parseFloat(product_price * product_amount).toFixed(2);
>>>>>>> e7ed3d553e640efbe0aedd33f438214083ef1525:google_tag_manager_advanced_tracking/static/src/js/website_sale_tracking.js
const dict = {
'event': 'add_to_cart',
'ecommerce': {
'currency': currency,
'value': amount,
'items': [{
'item_name': product_name,
'item_id': product_id,
'item_id': product_sku || product_id,
'price': product_price,
'quantity': product_amount,
}]
Expand Down Expand Up @@ -90,29 +113,52 @@ export class GoogleTagManagerAdvancedTracking extends Interaction {
}
}
this._pushInfo(dict);
<<<<<<< e9aa8e7dd3e7f495758de7710f7b5500db4fb4ca:google_tag_manager_advanced_tracking/static/src/interactions/website_sale_tracking.js
}

onCheckoutStartJs(ev) {
const dataTarget = document.querySelector("#cart_products");
if( dataTarget && Object.keys(dataTarget.dataset).length > 0) {
||||||| 3f4ea8024a54c6554045e9b425387a4c0a8d2755:google_tag_manager_advanced_tracking/static/src/js/website_sale_tracking.js
},
_onCheckoutStartJs: function () {
var dataTarget = $("#cart_products")[0];
if( Object.keys(dataTarget.dataset).length > 0) {
=======
},
_onCheckoutStartJs: function () {
var dataTarget = $("#cart_products")[0];
if(dataTarget && Object.keys(dataTarget.dataset).length > 0) {
>>>>>>> e7ed3d553e640efbe0aedd33f438214083ef1525:google_tag_manager_advanced_tracking/static/src/js/website_sale_tracking.js
try {
const currency = dataTarget.dataset.currency;
const value = dataTarget.dataset.value;
const info_string = dataTarget.dataset.cart_info;

// Robust parsing
let jsonString = info_string.replace(/\\/g, '\\\\').replace(/\'/g, '"');
jsonString = jsonString.replace(/:\s*None([,\}])/g, ': null$1');
jsonString = jsonString.replace(/:\s*True([,\}])/g, ': true$1');
jsonString = jsonString.replace(/:\s*False([,\}])/g, ': false$1');

const info = JSON.parse(jsonString);
const info = JSON.parse(info_string || '[]');
const allLines = Array.isArray(info) ? info : (info.items || []);
const rewardTotal = allLines
.filter((line) => line && line.is_reward_line)
.reduce((sum, line) => {
const price = Number(line.price || 0);
const quantity = Number(line.quantity || 1);
return sum + (price * quantity);
}, 0);
const items = allLines
.filter((line) => line && !line.is_reward_line)
.map((line) => ({
item_name: line.item_name,
item_id: line.item_id,
price: line.price,
quantity: line.quantity,
}));
const dict = {
'event':'begin_checkout',
'ecommerce':{
'currency': currency,
'value': value,
'items':info
'value': Number(value || 0),
'discount': Math.abs(rewardTotal),
'items': items,
}
}
this._pushInfo(dict);
Expand All @@ -124,6 +170,7 @@ export class GoogleTagManagerAdvancedTracking extends Interaction {
}
onCartView(element) {
try {
<<<<<<< e9aa8e7dd3e7f495758de7710f7b5500db4fb4ca:google_tag_manager_advanced_tracking/static/src/interactions/website_sale_tracking.js
if(element){
const info_string = element.dataset.cart_info;
// Attempt to fix common Python dict string issues for JSON parsing
Expand All @@ -136,6 +183,26 @@ export class GoogleTagManagerAdvancedTracking extends Interaction {
jsonString = jsonString.replace(/:\s*False([,\}])/g, ': false$1');

const info = JSON.parse(jsonString);
||||||| 3f4ea8024a54c6554045e9b425387a4c0a8d2755:google_tag_manager_advanced_tracking/static/src/js/website_sale_tracking.js
const cart = element[0]
if(cart){
const info_string = element[0].dataset.cart_info;
// Attempt to fix common Python dict string issues for JSON parsing
// 1. Escape existing backslashes
// 2. Replace single quotes with doublequotes
// 3. Replace Python boolean/none literals (only when they appear as values)
let jsonString = info_string.replace(/\\/g, '\\\\').replace(/\'/g, '"');
jsonString = jsonString.replace(/:\s*None([,\}])/g, ': null$1');
jsonString = jsonString.replace(/:\s*True([,\}])/g, ': true$1');
jsonString = jsonString.replace(/:\s*False([,\}])/g, ': false$1');

const info = JSON.parse(jsonString);
=======
const cart = element[0]
if(cart){
const info_string = element[0].dataset.cart_info;
const info = JSON.parse(info_string || '{}');
>>>>>>> e7ed3d553e640efbe0aedd33f438214083ef1525:google_tag_manager_advanced_tracking/static/src/js/website_sale_tracking.js
const dict = {
'event': 'view_cart',
'ecommerce': info
Expand All @@ -151,13 +218,17 @@ export class GoogleTagManagerAdvancedTracking extends Interaction {
try {
const info_string = confirmation.dataset.purchase_info;

// Robust parsing
let jsonString = info_string.replace(/\\/g, '\\\\').replace(/\'/g, '"');
jsonString = jsonString.replace(/:\s*None([,\}])/g, ': null$1');
jsonString = jsonString.replace(/:\s*True([,\}])/g, ': true$1');
jsonString = jsonString.replace(/:\s*False([,\}])/g, ': false$1');

const info = JSON.parse(jsonString);
// jQuery .data() auto-parses valid JSON into an object, handle both cases
let info;
if (typeof info_string === 'object') {
info = info_string;
} else {
let jsonString = info_string.replace(/\\/g, '\\\\').replace(/\'/g, '"');
jsonString = jsonString.replace(/:\s*None([,\}])/g, ': null$1');
jsonString = jsonString.replace(/:\s*True([,\}])/g, ': true$1');
jsonString = jsonString.replace(/:\s*False([,\}])/g, ': false$1');
info = JSON.parse(jsonString);
}
const dict = {
'event': 'purchase',
'ecommerce': info
Expand Down
31 changes: 21 additions & 10 deletions website_sale_advanced_tracking/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

from odoo import models


Expand All @@ -6,21 +8,30 @@ class SaleOrder(models.Model):

def prepare_purchase_information(self):
products = []
discount = 0.0
shipping = 0.0
for line in self.order_line:
products.append(
{
"item_id": line.product_id.default_code or line.product_id.id,
"item_name": line.product_id.name,
"item_category": line.product_id.categ_id.name,
"quantity": line.product_uom_qty,
"price": line.price_reduce_taxinc,
}
)
if getattr(line, "is_reward_line", False):
discount += abs(line.price_reduce_taxinc * line.product_uom_qty)
elif getattr(line, "is_delivery", False):
shipping += line.price_reduce_taxinc * line.product_uom_qty
else:
products.append(
{
"item_id": line.product_id.default_code or line.product_id.id,
"item_name": line.product_id.name,
"item_category": line.product_id.categ_id.name,
"quantity": line.product_uom_qty,
"price": line.price_reduce_taxinc,
}
)
res = {
"transaction_id": self.id,
"value": self.amount_total,
"tax": self.amount_tax,
"shipping": shipping,
"discount": discount,
"currency": self.currency_id.name,
"items": products,
}
return res
return json.dumps(res)
9 changes: 6 additions & 3 deletions website_sale_advanced_tracking/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

from odoo import models


Expand All @@ -9,10 +11,11 @@ def prepare_checkout_information(self):
for line in self:
res.append(
{
"item_name": line.name,
"item_name": line.product_id.name,
"item_id": line.product_id.default_code or line.product_id.id,
"price": (line.price_reduce_taxinc),
"price": line.price_reduce_taxinc,
"quantity": line.product_uom_qty,
"is_reward_line": getattr(line, "is_reward_line", False),
}
)
return res
return json.dumps(res)
4 changes: 2 additions & 2 deletions website_sale_advanced_tracking/views/templates.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<odoo>
<template id="cta_wrapper" inherit_id="website_sale.cta_wrapper">
<xpath expr="//a[@id='add_to_cart']" position="attributes">
<attribute name="t-att-data-product_id">product.default_code</attribute>
<attribute name="t-att-data-product_id">product.id</attribute>
<attribute name="t-att-data-product_name">product.name</attribute>
<attribute name="t-att-data-product_price">combination_info['price']</attribute>
<attribute name="t-att-data-product_sku">product.default_code</attribute>
Expand Down Expand Up @@ -39,7 +39,7 @@
</xpath>
</template>
<template id="cart_lines" inherit_id="website_sale.cart_lines">
<xpath expr="//div[@id='cart_products']" position="attributes">
<xpath expr="//*[@id='cart_products']" position="attributes">
<attribute name="t-att-data-cart_info">website_sale_order.website_order_line.prepare_checkout_information()</attribute>
<attribute name="t-att-data-currency">website.currency_id.name</attribute>
<attribute name="t-att-data-value">website_sale_order.amount_total</attribute>
Expand Down
Loading