So I've been fiddling with this for a while now and I can't wrap my head around how analytics does it's calculations on purchases when updating an order with new/changed products.
I'm utilizing the datalayer(dl) and push my purchase event to the dl, which GTM listens to via a trigger event, all standard so far.
{
"event": "purchase",
"currencyCode": "SEK",
"ecommerce": {
"purchase": {
"actionField": {
"id": "123",
"tax": 30.0,
"action": "purchase"
},
"products": [
{
"name": "name",
"id": "123",
"price": "5.0",
"brand": "brand",
"category": "category",
"quantity": 2
}
]
}
}
}
But then our customers has the ability to change their orders. So with a bit of research On here I was able to defer that you can add products with a negative quantity on the existing order to remove products after a changed order.
So this resulted in, something not optimal but it works for the orders products atleast. In this case I want one more item of the same. So I do this:
{
"event": "purchase",
"currencyCode": "SEK",
"ecommerce": {
"purchase": {
"actionField": {
"id": "123",
"tax": newTax -= oldTax,
"action": "purchase"
},
"products": [
{
"name": "name",
"id": "123",
"price": "5.0",
"brand": "brand",
"category": "category",
"quantity": 3
},
{
"name": "name",
"id": "123",
"price": "5.0",
"brand": "brand",
"category": "category",
"quantity": -2
}
]
}
}
}
And it works for everything except the total of the purchase. Since that's calculated based on the products in the order why doesn't that update automatically when I update the order? Do I need to send in the oldTotal -= newTotal as well or is there a delay in the recalculations in analytics?
Instead of letting it calculate the total revenue on its own, have you tried adding the total revenue, total tax and total shipping on your own. These fields are present in the actionField as follows:-
"actionField": {
"id": "123",
"action": "purchase"
'revenue': 'newRev - oldRev', // difference of new revenue and old revenue
'tax':'newTax - oldTax', // difference of new tax and old tax
'shipping': 'newShipping - oldShipping' // difference of new shipping and old shipping
},
Of course do add the products as well.
In the canned GA reports, it will automatically add the old revenue and the new revenue amounts and use that as the revenue total.
Related
I was asked to store leads like below in Marketo's lead database through rest api "POST /rest/v1/leads.json".
{
"action": "createOnly",
"lookupField": "email",
"input": [{
"email": "kjashaedd-1#klooblept.com",
"firstName": "Kataldar-1",
"postalCode": "04828",
"property": [{
"type": "land",
"status": "available"
},
{
"type": "car",
"status": "sold out"
},
{
"type": "bike",
"status": "sold out"
},
{
"type": "laptops",
"status": "available"
}
]
},
{
"email": "kjashaedd-2#klooblept.com",
"firstName": "Kataldar-2",
"postalCode": "04828",
"property": [{
"type": "land",
"status": "sold out"
},
{
"type": "car",
"status": "available"
},
{
"type": "bike",
"status": "sold out"
},
{
"type": "laptops",
"status": "available"
}
]
}
]
}
Input field is not in flat json structure. What could be the best approach? Do I really need to use custom objects in this case? Can I dump "property" object as it is in the lead database and use velocity script to parse it ?
If 'Property' is a custom object, you'll want to call that separately for the record and associated the record with that object via the custom object API
So you can push (create) the record first and then associate (add) the custom object to the record.
You can create a List<Dictionary<string,object>> in C# and retrieve the data and then store it using Entity Framework.
I am considering .Net framework in this case
Facing an issue when creating a order via WooCommerce rest API. There are two issues:
Order Note
When creating order via Desktop:-
New Order of "BANK Transfer" as a payment creating two order note
Order status changed from pending payment to on hold
For order stock reduced
When creating order via Mobile:-
New order with "Bank Transfer" as a payment method creating three order note:-
1. Order status changed from pending payment to processing
2. Order stock reduced
3. Order status changed from pending payment to on hold
Customer Receiving a email with status processing, while the order status is on-hold
I tried to pass order status=on-hold from API when creating a order and updating a order payment details. But issue is still persist.
Order create api
POST wc-api/v3/orders/
Body
{
"order": {
"customer_id": 6925,
"billing_address": {
"first_name": "Android",
"last_name": "Testing",
"address_1": "Address of Developer",
"address_2": "Cengkareng",
"city": "Jakarta Barat",
"state": "6",
"postcode": "12345",
"country": "ID",
"email": "ankurgecr#gmail.com",
"phone": "1234567890"
},
"shipping_address": {
"first_name": "Android",
"last_name": "Testing",
"address_1": "Address of Developer",
"address_2": "Cengkareng",
"city": "Jakarta Barat",
"state": "6",
"postcode": "12345",
"country": "ID"
},
"line_items": [
{
"product_id": 32776,
"quantity": 1,
"subtotal": 10000,
"total": 10000,
"variations": {
"Color": "Blue"
}
}
],
"fee_lines": [
{
"title": "Rp",
"total": 846
}
],
"shipping_lines": [
{
"method_id": "OKE",
"method_title": "JNE OKE",
"total": 29500
}
],
"is_vat_exempt": false
}
}
Order update API
POST wc-api/orders/[orderID]
BODY
{
"order": {
"status": "on-hold",
"payment_details": {
"method_id": "bacs",
"method_title": "Bank Transfer BCA / MANDIRI",
"paid": true
},
"set_paid": true
}
}
Custoemr should receive a email of order status= on-hold.
I'm attaching a image for actual result.
Note: Is is working fine if we are placing a orde from website checkout, only the issue is with rest API.
Some time ago I have implemented Google Analytics Advanced Ecommerce using GTM DataLayer.
After year of usage we have decided to change Naming of products and Added categories/brands for each transaction, also was changed all SKU/ID.
But nothing changed in reports. Names of all old products still remains old, no Brand/Category included in reports.
How can I update Product Data in reports and add categories/brands?
Thanks!
PS New products seems to be OK, but also no Category/Brand.
Here is example of DataLayer:
// Product Details
dataLayer.push({
'ecommerce': {
'currencyCode': 'EUR',
'detail': {
'products': [{
'name': 'Tetris', // Name or ID is required.
'id': 'g395',
'sku': 'g395',
'category': 'Toys & Games',
'brand': 'Mojo-jojo!'
}]
}
}
});
//// Transaction
dataLayer.push({
"ecommerce": {
"currencyCode": "EUR",
"checkout": {
"actionField": {
"step": 4
}
},
"purchase": {
"actionField": {
"id": 13202,
"affiliation": "www.mojo-jojo.com",
"revenue": 0.01
},
"products": [{
"id": "g105",
"sku": "g105",
"name": "Duracell AA",
"brand": "Mojo-jojo!",
"category": "Accessories",
"price": 0.7,
"quantity": 1
}]
}
},
"transactionId": 13202,
"transactionTotal": 0.01,
"transactionProducts": [{
"id": "g105",
"sku": "g105",
"name": "Duracell AA",
"brand": "Mojo-jojo!",
"category": "Accessories",
"price": 0.7,
"quantity": 1
}],
"event": "transaction",
"product_ids": [105],
"num_items": 1,
"conversion_value": 0.01
});
Google analytics data is read only. As soon as the data is inserted you can not change it / updated.
However now that you have changed it any data being inserted from now on will contain the new names.
I have taken the Blog App, added a Category ContentType as a field in the BlogPost ContentType and built a query to factor Category into the results.
But I am having trouble with the In-ValueProvider. Following the example here the Visual Query Designer seems to be ignoring the incoming value from my ModuleDataSource.
I have double checked the In-Stream name, my Entity names, case, TestParameters, etc. Are there any known bugs in 2sxc 8.44 and up that would cause this issue? What have I missed?
In this case I am using a RelationshipFilter. Relationship is "Category". Filter is "[In:Config:Category]". I can switch out to a [Querystring:Category] and that works fine and runs all my code.
Thanks for reading.
OK I found a workaround.
It turns out that the In-ValueProvider is working but it's struggling with the Category of my BlogPost I think because Category is an entity.
For background I have a BlogPost ContentType, a Category ContentType, and an Articles Home Header ContentType. Articles Home Header sets both the header info for the articles page and the Category entity.
For some reason the RelationshipFilter is having trouble comparing the Category entities between Articles Home Header and BlogPost. I tried the following for my Filter and neither worked:
[In:Config:Category]
[In:Config:Category:Title]
I wonder if this is a case sensitivity issue, a bug, or if I am just misunderstanding the filter syntax.
To work around I created a temp field called TempCategory in my Articles Home Header and used [In:Config:TempCategory] for the filter.
That worked.
For reference here is a snippet from the Query:
{
"Config": [
{
"Title": "Coaching Articles",
"SubTitle": "",
"Image": "/Portals/0/uploadedimages/AcademicPrograms/Christ_College/crosswise-hero.jpg",
"ImageAlt": "Crosswise stained glass",
"Category": [
{
"Id": 2716,
"Title": "Coaching"
}
],
"Id": 3118,
"Modified": "2016-06-21T10:44:21.9Z",
"_2sxcEditInformation": {
"sortOrder": 0
}
}
],
"Paging": [
{
"Title": "Paging Information",
"PageSize": 10,
"PageNumber": 1,
"ItemCount": 0,
"PageCount": 0,
"Id": 0,
"Modified": "0001-01-01T00:00:00Z",
"_2sxcEditInformation": {
"entityId": 0,
"title": "Paging Information"
}
}
],
,
"Default": [
{
"Title": "Protect Your Players and Your Program: An Athletic Leader's Legal Duties",
"UrlKey": "an-athletic-leaders-legal-duties",
"PublishingGroup": null,
"PublicationMoment": "2016-06-15T00:00:00Z",
"Image": "/Portals/0/uploadedimages/AcademicPrograms/Graduate/Coaching/an_athletic_leaders_legal_duty.jpg",
"ImageSquare": false,
"Teaser": "<p>When the clock started on the new year earlier this month, all but one state joined the growing legal effort to protect and prevent concussions and head injuries among America’s young.</p>",
"Body": "<p><strong>When the clock started on the new year earlier this month,</strong> all but one state joined the growing legal effort to protect and prevent concussions and head injuries among America’s young.</p>\n<p>As sports-related injuries and issues continue to dominate the headlines and influence programs throughout the country, laws like “return-to-play” are becoming a sign of the times when it comes to protecting players and athletic programs alike. The world of athletics is experiencing a significant shift in the perception of the roles and responsibilities of coaches, schools and athletic personnel.</p>",
"DesignedContent": [],
"Tags": [
{
"Id": 2576,
"Title": "coaching"
},
{
"Id": 2575,
"Title": "management"
},
{
"Id": 2574,
"Title": "sports"
},
{
"Id": 3035,
"Title": "legal"
}
],
"Author": [
{
"Id": 3030,
"Title": "Shaleek Blackburn"
}
],
"ImageAlt": "Referee holding a red",
"Thumbnail": "",
"ThumbnailAlt": "",
"RelatedArticles": [
{
"Id": 2564,
"Title": "Athletic Personnel's Duty To Warn"
},
{
"Id": 2565,
"Title": "Get A Better Grip On Bullying"
},
{
"Id": 2717,
"Title": "Good Coaching Develops Exceptional Athletes and People"
}
],
"Category": [
{
"Id": 2716,
"Title": "Coaching"
}
],
"ArticleRelationships": null,
"Id": 2513,
"Modified": "2016-06-15T19:32:17.913Z",
"_2sxcEditInformation": {
"entityId": 2513,
"title": "Protect Your Players and Your Program: An Athletic Leader's Legal Duties"
}
}
]
}
I want to find the ceo of IBM. What would be the MQL query for this?
The MQL for this search looks like the following.
This particular instance may be a tat more complicated than necessary because I got it initially produced from a Freebase interactive search and then simply added/improved the filters manually.
I verified it with various company names with relative success, i.e. it works provided that the underlying data is properly codified in Freebase (some companies are missing, for some companies the leadership data is incomplete etc.)
There are a few tricks to this query:
the company name in u0 fitler needs to match precisely the company name as recorded in Freebase. You could use a contains predicate rather than an equal one, but that could introduce many irrelevant hits. For example you need to use "IBM", "Apple Inc.", "General Motors" rather than common alternatives to these names ("International Business Machines", "Apple", "GM"...")
the u1 filter, on the leadership role is expressed in a extensive One of predicate because unfortunately the nomenclature for these roles is relatively loose, with duplicates (e.g. could be CEO or Chief Executive Officer) and with the fact that the role of CEO is often coupled with other corporate roles such as Chairman [of the board] and/or President etc. I hand picked this list by first looking up (in Freebase) the instances of Leadership Roles which contained "CEO" or "Chief Executive".
the u2 filter expresses that the to date should be empty, to select only the person currently in office, as opposed to former CEOs (for which hopefully Freebase recorded the end date of their tenure).
Depending on your application, you may need to test that the query returns one and exactly one record, and adapt accordingly if it doesn't.
Freebase MQL editor is a convenient tool test and edit with this kind of queries.
[
{
"from": null,
"id": null,
"limit": 20,
"organization": {
"id": null,
"name": null,
"optional": true
},
"person": {
"id": null,
"name": null,
"optional": true
},
"role": {
"id": null,
"name": null,
"optional": true
},
"s0:type": [
{
"id": "/organization/leadership",
"link": [
{
"timestamp": [
{
"optional": true,
"type": "/type/datetime",
"value": null
}
],
"type": "/type/link"
}
],
"type": "/type/type"
}
],
"sort": "s0:type.link.timestamp.value",
"title": null,
"to": null,
"type": "/organization/leadership",
"u0:organization": [
{
"id": null,
"name": "IBM",
"type": "/organization/organization"
}
],
"u1:role": [
{
"id": null,
"name|=": ["Chief Executive Officer", "President and CEO", "Chairman and CEO", "Interim CEO", "Interim Chief Executive Officer", "Founder and CEO", "Chairman, President and CEO", "Managing Director and CEO", "Executive Vice President and Chief Operating Officer", "Co-Founder, Chairman and Chief Executive Officer"],
"type": "/organization/role"
}
],
"u2:to": [
{
"value": null,
"optional": "forbidden"
}
]
}
]
Sample return (for "IBM", specifically)
{
"code": "/api/status/ok",
"result": [{
"from": "2012-01-01",
"id": "/m/09t7b08",
"organization": {
"id": "/en/ibm",
"name": "IBM"
},
"person": {
"id": "/en/virginia_m_rometty",
"name": "Virginia M. Rometty"
},
"role": {
"id": "/en/chairman_president_and_ceo",
"name": "Chairman, President and CEO"
},
"s0:type": [{
"id": "/organization/leadership",
"link": [{
"timestamp": [{
"type": "/type/datetime",
"value": "2010-01-23T08:02:57.0006Z"
}],
"type": "/type/link"
}],
"type": "/type/type"
}],
"title": "Chairman, President and CEO",
"to": null,
"type": "/organization/leadership",
"u0:organization": [{
"id": "/en/ibm",
"name": "IBM",
"type": "/organization/organization"
}],
"u1:role": [{
"id": "/en/chairman_president_and_ceo",
"type": "/organization/role"
}],
"u2:to": []
}