Repository: saleor/saleor

Issue:
AttributeError: 'OrderLine' object has no attribute 'get_price_per_item'
When placing an order I got the following error from the Google Analytics reporting script:

```
ERROR saleor.order.signals Recording order in analytics failed [PID:65745:Thread-255]
Traceback (most recent call last):
  File "/Users/marcin/mirumee/saleor/saleor/order/signals.py", line 20, in order_status_change
    analytics.report_order(order.tracking_client_id, order)
  File "/Users/marcin/mirumee/saleor/saleor/core/analytics.py", line 55, in report_order
    for ol in group]
  File "/Users/marcin/mirumee/saleor/saleor/core/analytics.py", line 55, in <listcomp>
    for ol in group]
AttributeError: 'OrderLine' object has no attribute 'get_price_per_item'
```

It probably broke with our recent changes (dropping Satchless or merging new prices library). As this is a Celery task, the error is visible in the console but doesn't block the site.


Discussion:
Yep, `get_price_per_item` getter has been superseded by the `unit_price` combined field on model

Resolving patch:
diff --git a/saleor/core/analytics.py b/saleor/core/analytics.py
--- a/saleor/core/analytics.py
+++ b/saleor/core/analytics.py
@@ -21,38 +21,48 @@ def get_client_id(request):
 
 
 @shared_task
-def ga_report(tracking_id, client_id, what, extra_info=None,
-              extra_headers=None):
-    ga.report(tracking_id, client_id, what, extra_info=extra_info,
-              extra_headers=extra_headers)
+def ga_report(
+        tracking_id, client_id, payloads, extra_headers=None, **extra_data):
+    ga.report(
+        tracking_id, client_id, payloads, extra_headers=extra_headers,
+        **extra_data)
 
 
-def _report(client_id, what, extra_info=None, extra_headers=None):
+def _report(client_id, payloads, extra_headers=None, **extra_data):
     tracking_id = getattr(settings, 'GOOGLE_ANALYTICS_TRACKING_ID', None)
     if tracking_id and client_id:
-        ga_report(tracking_id, client_id, what, extra_info=extra_info,
-                  extra_headers=extra_headers)
+        ga_report(
+            tracking_id, client_id, payloads, extra_headers=extra_headers,
+            **extra_data)
 
 
-def report_view(client_id, path, language, headers):
+def get_order_payloads(order):
+    items = [
+        ga.item(
+            ol.product_name, ol.unit_price.gross, quantity=ol.quantity,
+            item_id=ol.product_sku)
+        for ol in order]
+    return ga.transaction(
+        order.id, items, revenue=order.total.gross,
+        shipping=order.shipping_price.gross)
+
+
+def report_order(client_id, order):
+    payloads = get_order_payloads(order)
+    _report(client_id, payloads)
+
+
+def get_view_payloads(path, language, headers):
     host_name = headers.get('HTTP_HOST', None)
     referrer = headers.get('HTTP_REFERER', None)
-    pv = ga.PageView(path, host_name=host_name, referrer=referrer)
-    extra_info = ga.SystemInfo(language=language)
+    return ga.pageview(
+        path, host_name=host_name, referrer=referrer, language=language)
+
+
+def report_view(client_id, path, language, headers):
+    payloads = get_view_payloads(path, language, headers)
     extra_headers = {}
     user_agent = headers.get('HTTP_USER_AGENT', None)
     if user_agent:
         extra_headers['user-agent'] = user_agent
-    _report(client_id, pv, extra_info=extra_info, extra_headers=extra_headers)
-
-
-def report_order(client_id, order):
-    items = [
-        ga.Item(
-            ol.product_name, ol.get_price_per_item(), quantity=ol.quantity,
-            item_id=ol.product_sku)
-        for ol in order]
-    trans = ga.Transaction(
-        '%s' % (order.id,), items, revenue=order.get_total(),
-        shipping=order.shipping_price)
-    _report(client_id, trans, {})
+    _report(client_id, payloads, extra_headers=extra_headers)


Test patch:
diff --git a/tests/test_analytics.py b/tests/test_analytics.py
new file mode 100644
--- /dev/null
+++ b/tests/test_analytics.py
@@ -0,0 +1,47 @@
+from decimal import Decimal
+
+from saleor.core.analytics import (
+    get_order_payloads, get_view_payloads, report_order, report_view)
+
+
+def test_get_order_payloads(order_with_lines):
+    order = order_with_lines
+
+    generator = get_order_payloads(order)
+    data = list(generator)
+    assert len(data) == order.lines.count() + 1
+
+    transaction = data[0]
+    assert transaction['ti'] == order.pk
+    assert transaction['cu'] == order.total.currency
+    assert Decimal(transaction['tr']) == order.total.gross.amount
+    assert Decimal(transaction['tt']) == order.total.tax.amount
+    assert Decimal(transaction['ts']) == order.shipping_price.gross.amount
+
+    for i, line in enumerate(order):
+        item = data[i + 1]
+        assert item['ti'] == order.pk
+        assert item['in'] == line.product_name
+        assert item['ic'] == line.product_sku
+        assert item['iq'] == str(int(line.quantity))
+        assert item['cu'] == line.unit_price.currency
+        assert Decimal(item['ip']) == line.unit_price.gross.amount
+
+
+def test_report_order_has_no_errors(order_with_lines):
+    report_order('', order_with_lines)
+
+
+def test_get_view_payloads():
+    headers = {'HTTP_HOST': 'getsaleor.com', 'HTTP_REFERER': 'example.com'}
+    generator = get_view_payloads('/test-path/', 'en-us', headers)
+    data = list(generator)[0]
+    assert data['dp'] == '/test-path/'
+    assert data['dh'] == 'getsaleor.com'
+    assert data['dr'] == 'example.com'
+    assert data['ul'] == 'en-us'
+
+
+def test_report_view_has_no_errors():
+    headers = {'HTTP_HOST': 'getsaleor.com', 'HTTP_REFERER': 'example.com'}
+    report_view('', '/test-path/', 'en-us', headers)