From 4e607fb856842b43192511b1b4eaff19d2052b9a Mon Sep 17 00:00:00 2001 From: Artemiy Date: Fri, 17 Aug 2018 18:02:31 +0300 Subject: [PATCH] #504 Extend sending info about products to YA and GA systems (#520) * Extend sending info about products to YA and GA systems Self-review fixes * Create todo for a product's brand * Create todo for html element's properties * Apply linter rules --- front/js/components/category.es6 | 25 +++++++----- front/js/components/order.es6 | 18 +++++---- front/js/components/product.es6 | 42 ++++++++++++++------ front/js/shared/{yandex.es6 => tracking.es6} | 23 +++++++---- templates/catalog/category.html | 2 +- templates/catalog/category_products.html | 6 ++- templates/catalog/product.html | 3 +- templates/ecommerce/order/table_form.html | 2 +- 8 files changed, 79 insertions(+), 42 deletions(-) rename front/js/shared/{yandex.es6 => tracking.es6} (82%) diff --git a/front/js/components/category.es6 b/front/js/components/category.es6 index 6f712af6..37fdcee1 100644 --- a/front/js/components/category.es6 +++ b/front/js/components/category.es6 @@ -1,5 +1,6 @@ (() => { const DOM = { + $h1: $('.category-title'), $productsOnPage: $('.js-products-showed-count'), $productsList: $('#products-wrapper'), $viewType: $('#category-right'), @@ -158,21 +159,25 @@ * Publish 'onCartUpdate' event on success. */ function buyProduct(event) { - const buyInfo = () => { - const product = $(event.target); - const count = product.closest('.js-order').find('.js-product-count').val(); + const getProductData = () => { + const $product = $(event.target); + const quantity = $product.closest('.js-order').find('.js-product-count').val(); return { - count: parseInt(count, 10), - id: parseInt(product.attr('productId'), 10), + id: parseInt($product.attr('productId'), 10), + name: $product.attr('productName'), + quantity: parseInt(quantity, 10), + category: DOM.$h1.data('name'), }; }; - const { id, count } = buyInfo(); - server.addToCart(id, count) - .then((data) => { - mediator.publish('onCartUpdate', data); - mediator.publish('onProductAdd', [id, count]); + const data = getProductData(); + const { id, quantity } = data; + + server.addToCart(id, quantity) + .then((newData) => { + mediator.publish('onCartUpdate', newData); + mediator.publish('onProductAdd', [data]); }); } diff --git a/front/js/components/order.es6 b/front/js/components/order.es6 index fe491b67..d1bdc722 100644 --- a/front/js/components/order.es6 +++ b/front/js/components/order.es6 @@ -9,6 +9,7 @@ submit: '#submit-order', fullForm: '#order-form-full', productCount: '.js-prod-count', + productPrice: '.js-product-price', remove: '.js-remove', paymentOptions: 'input[name=payment_type]', defaultPaymentOptions: 'input[for=id_payment_type_0]', @@ -62,9 +63,9 @@ return $(DOM.productRows).map((_, el) => { const $el = $(el); return { - id: $el.attr('data-table-id'), name: $el.find('.js-product-link').text(), quantity: $el.find(DOM.productCount).val(), + price: parseInt($el.find(DOM.productPrice).attr('productPrice'), 10), }; }).get(); } @@ -151,14 +152,15 @@ function changeProductCount(event) { const productId = getElAttr(event, 'productId'); const countDiff = event.target.value - getElAttr(event, 'productLastCount'); + const data = { + id: productId, + quantity: Math.abs(countDiff), + }; + server.changeInCart(productId, event.target.value) - .then((data) => { - mediator.publish('onCartUpdate', data); - if (countDiff > 0) { - mediator.publish('onProductAdd', [productId, countDiff]); - } else { - mediator.publish('onProductRemove', [productId, Math.abs(countDiff)]); - } + .then((newData) => { + mediator.publish('onCartUpdate', newData); + mediator.publish(countDiff > 0 ? 'onProductAdd' : 'onProductRemove', [data]); }); } diff --git a/front/js/components/product.es6 b/front/js/components/product.es6 index 9f89ac8e..8e7ded4f 100644 --- a/front/js/components/product.es6 +++ b/front/js/components/product.es6 @@ -26,11 +26,11 @@ }; const productId = DOM.$addToCart.attr('data-id'); - if (productId) mediator.publish('onProductDetail', productId); const init = () => { setUpListeners(); changeOneClickBtnState(); + publishDetail(); }; function setUpListeners() { @@ -51,6 +51,23 @@ DOM.$more_text_toggle.on('click', helpers.toggleText); } + function getProductData() { + return { + id: productId, + name: DOM.$addToCart.data('name'), + category: DOM.$addToCart.data('category'), + quantity: parseInt(DOM.$counter.val(), 10), + }; + } + + /** + * Publish onProductDetail event. + */ + function publishDetail() { + const { id, name, category } = getProductData(); + if (id) mediator.publish('onProductDetail', [{ id, name, category }]); + } + /** * Initialize fancyBox on specific index image. */ @@ -75,10 +92,13 @@ */ function oneClick() { helpers.setDisabledState(DOM.$oneClick, 'Ожидайте...'); - const productCount = DOM.$counter.val(); - server.oneClickBuy(productId, productCount, DOM.$phone.val()) + + const data = getProductData(); + const { id, quantity } = data; + + server.oneClickBuy(id, quantity, DOM.$phone.val()) .then(() => { - mediator.publish('onOneClickBuy', [productId, productCount, DOM.$h1.text()]); + mediator.publish('onOneClickBuy', [data]); // Set timeout to wait handling of onOneClickBuy setTimeout(() => { window.location.href = '/shop/order-success'; @@ -110,15 +130,13 @@ } function buyProduct() { - const { id, count } = { - id: productId, - count: DOM.$counter.val(), - }; + const data = getProductData(); + const { id, quantity } = data; - server.addToCart(id, count) - .then((data) => { - mediator.publish('onCartUpdate', data); - mediator.publish('onProductAdd', [id, count]); + server.addToCart(id, quantity) + .then((newData) => { + mediator.publish('onCartUpdate', newData); + mediator.publish('onProductAdd', [data]); }); } diff --git a/front/js/shared/yandex.es6 b/front/js/shared/tracking.es6 similarity index 82% rename from front/js/shared/yandex.es6 rename to front/js/shared/tracking.es6 index cada86a4..e4dcd4f9 100644 --- a/front/js/shared/yandex.es6 +++ b/front/js/shared/tracking.es6 @@ -26,25 +26,32 @@ const yaTracker = new YATracker(window.dataLayer, 'RUB'); // Ignore ESLintBear (no-undef) const gaTracker = new GATracker(ga, 'ecommerce'); // Ignore ESLintBear (block-scoped-var) - const orderData = { id: 'DummyId' }; + + // @todo #504:60m Send `purchase` event to YA and GA after a success purchase. + // This will allow us to send order's id. Currently we send the event after + // submitting of the purchase button with the dummy order's id. + // See the parent issue for a detail. + + // @todo #504:30m Send info about product's brand to YA and GA. + + // Use a dummy order's id, because we do not wait complete processing of + // purchase request. + const orderData = { id: 1 }; const init = () => { setUpListeners(); }; function setUpListeners() { - mediator.subscribe('onOneClickBuy', (_, id, quantity, name) => { + mediator.subscribe('onOneClickBuy', (_, productsData) => { reachGoal('CMN_BUY_SEND'); reachGoal('FAST_BUY_SEND'); - const productsData = { id, quantity, name }; yaTracker.purchase([productsData], orderData); gaTracker.purchase([productsData], orderData); }); mediator.subscribe('onOrderSend', (_, products) => { reachGoal('CMN_BUY_SEND'); reachGoal('FULL_BUY_SEND'); - // Use a dummy order's id, because we do not wait complete processing of - // purchase request. yaTracker.purchase(products, orderData); gaTracker.purchase(products, orderData); }); @@ -52,14 +59,14 @@ yaTracker.remove(products); }); // We receive an onProductAdd event from a category and a product pages - mediator.subscribe('onProductAdd', (_, id, quantity) => { - yaTracker.add([{ id, quantity }]); + mediator.subscribe('onProductAdd', (_, data) => { + yaTracker.add([data]); }); mediator.subscribe('onProductRemove', (_, id, quantity) => { reachGoal('DELETE_PRODUCT'); yaTracker.remove([{ id, quantity }]); }); - mediator.subscribe('onProductDetail', (_, id) => yaTracker.detail([{ id }])); + mediator.subscribe('onProductDetail', (_, data) => yaTracker.detail([data])); mediator.subscribe('onBackCallSend', () => reachGoal('BACK_CALL_SEND')); DOM.$searchForm.submit(() => reachGoal('USE_SEARCH_FORM')); diff --git a/templates/catalog/category.html b/templates/catalog/category.html index 87b1ef73..5e1291a8 100644 --- a/templates/catalog/category.html +++ b/templates/catalog/category.html @@ -5,7 +5,7 @@ {% block content %} {% breadcrumbs_with_siblings page %} -

{{ page.display_h1|capfirst }}

+

{{ page.display_h1|capfirst }}

diff --git a/templates/catalog/category_products.html b/templates/catalog/category_products.html index 5fc0f8da..36425756 100644 --- a/templates/catalog/category_products.html +++ b/templates/catalog/category_products.html @@ -38,8 +38,12 @@
+ {% comment %} + @todo #504:15m Rename `productId` like format of properties to `data-product-id`. + {% endcomment %}
diff --git a/templates/catalog/product.html b/templates/catalog/product.html index 9ccd9686..c06ae373 100644 --- a/templates/catalog/product.html +++ b/templates/catalog/product.html @@ -62,7 +62,8 @@

{{ page.display_h1 }}

+ data-id="{{ product.id }}" data-name="{{ product.name }}" + data-category="{{ product.category.name }}">В корзину

Купить в один клик

Оформление заказа name="prod-count" productId="{{ id }}" productLastCount="{{ position.quantity }}">
+ productId="{{ id }}" productPrice="{{ position.price }}"> {{ position.price|humanize_price }} руб.