diff --git a/admin-costs-plugin/garr_costs/content/costs/tables.py b/admin-costs-plugin/garr_costs/content/costs/tables.py
index c182e4c30e5389f94d816e9092566999b61d5160..80ab5708d4e7186692115c58c7e633d063d9f107 100644
--- a/admin-costs-plugin/garr_costs/content/costs/tables.py
+++ b/admin-costs-plugin/garr_costs/content/costs/tables.py
@@ -1,3 +1,4 @@
+import logging
 from django.contrib.humanize.templatetags import humanize
 from django.utils import text
 from django.utils.translation import ugettext_lazy as _
@@ -12,15 +13,20 @@ from django import forms as django_forms
 from horizon import tables
 from horizon import forms
 
+LOG = logging.getLogger(__name__)
 def get_link(resource):
-    if resource['resource_type'] == 'instance':
+    resource_type = resource.get('resource_type', None)
+    if resource_type == 'instance':
         link =  'horizon:project:instances:detail'
-    elif resource['resource_type'] == 'volume':
+    elif resource_type == 'volume':
         link = 'horizon:project:volumes:detail'
     else:
         return ''
-
-    return urlresolvers.reverse(link, args=(resource['id'],))
+    try:
+        url = urlresolvers.reverse(link, args=(resource['id'],))
+    except Exception:
+        url = ''
+    return url
 
 class CostsTable(tables.DataTable):
     resource = tables.WrappingColumn('name', verbose_name=_('Resource Name'),
@@ -33,7 +39,7 @@ class CostsTable(tables.DataTable):
     flavor = tables.Column('flavor', verbose_name=_("Resource flavor"))
     value = tables.Column('value', verbose_name=_('Usage'))
     unit = tables.Column('unit', verbose_name=_("Unit"))
-    price = tables.Column('price', verbose_name=_("Price"))
+    price = tables.Column('price', verbose_name=_("Latest price"))
     cost = tables.Column('cost', verbose_name=_("Total Cost"))
 
     def get_object_id(self, resource):
diff --git a/admin-costs-plugin/garr_costs/content/costs/utils.py b/admin-costs-plugin/garr_costs/content/costs/utils.py
index 0d51798b840cdf9280943abbb3b6750d35edba2d..84f833d03589c56ba3c9ade687b28b48b774b58d 100644
--- a/admin-costs-plugin/garr_costs/content/costs/utils.py
+++ b/admin-costs-plugin/garr_costs/content/costs/utils.py
@@ -26,20 +26,14 @@ def get_measure_value(measures, metric, resource):
         result = convert_nanoseconds(result)
     return result
 
-def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_client):
-    unit = 'GB*hour'
-    try:
-        api.cinder.volume_get(request, resource['id'])
-    except Exception:
-        raise Exception('Volume %s not found' % resource['id'])
-
+def compute_volume_cost(resource, price, start_date, end_date, gnocchi_client):
     measures = [measure[2] for measure in gnocchi_client.metric.get_measures(
-        'volume.size', start=usage_start, stop=usage_end,
+        'volume.size', start=start_date, stop=end_date,
         aggregation='max', resource_id=resource['id']
     )]
 
     if not measures:
-        return 0, 0, unit
+        return 0, 0
 
     usage = sum(measures)/len(measures)
     cost = '{0:.2f}'.format(
@@ -47,16 +41,170 @@ def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_c
         )
     usage = '{0:.2f}'.format(usage)
     
-    return cost, usage, unit
+    return cost, usage
 
-def get_instance_usage(resource, price, usage_start, usage_end, gnocchi_client):
-    unit = 'hour'
 
-    cpu_util_measures = gnocchi_client.metric.get_measures(metric=resource['metrics']['cpu_util'],start=usage_start,stop=usage_end)
+def get_volume_usage(request, resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'GB*hour'
+    try:
+        api.cinder.volume_get(request, resource['id'])
+    except Exception:
+        raise Exception('Volume %s not found' % resource['id'])
+
+    cost = '{0:.2f}'.format(0)
+    usage = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_volume_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+    return cost, usage, unit
+
+def compute_instance_cost(resource, price, start_date, end_date, gnocchi_client):
+    cpu_util_measures = gnocchi_client.metric.get_measures(metric=resource['metrics']['cpu_util'],start=start_date,stop=end_date)
     hours_interval = (len(cpu_util_measures)*5)/60
         
     cost = '{0:.2f}'.format(
         round(hours_interval * price, 2)
         )
 
-    return cost, hours_interval, unit
+    return cost, hours_interval
+
+def get_instance_usage(resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'hour'
+    usage = 0
+    cost = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_instance_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+    return cost, usage, unit
diff --git a/admin-costs-plugin/garr_costs/content/costs/views.py b/admin-costs-plugin/garr_costs/content/costs/views.py
index 6e7ea6b3478322a756a7eaf149916c36c1b006ec..f9079eb1eb571117ecaf0ad80c6bfaa6deb4c0df 100644
--- a/admin-costs-plugin/garr_costs/content/costs/views.py
+++ b/admin-costs-plugin/garr_costs/content/costs/views.py
@@ -114,7 +114,7 @@ class IndexView(tables.DataTableView):
                 resource_usage_end = usage_end
 
             try:
-                price, cost_unit = self.get_price(resource, self.request, session)
+                price_list, cost_unit = self.get_price(resource, self.request, session)
             except Exception as e:
                 LOG.error("Unable to fetch price for resource %s of type %s" % (resource_name, resource['type']))
                 continue
@@ -124,10 +124,10 @@ class IndexView(tables.DataTableView):
 
             try:
                 if resource['type'] == 'instance': 
-                    cost, usage, unit = get_instance_usage(resource, price, resource_usage_start, resource_usage_end, client)
+                    cost, usage, unit = get_instance_usage(resource, price_list, resource_usage_start, resource_usage_end, client)
                     resource_flavor = resource['flavor_name']
                 elif resource['type'] == 'volume':
-                    cost, usage, unit = get_volume_usage(self.request, resource, price, resource_usage_start, resource_usage_end, client)
+                    cost, usage, unit = get_volume_usage(self.request, resource, price_list, resource_usage_start, resource_usage_end, client)
                     resource_flavor = api.cinder.volume_type_get(self.request, resource['volume_type']).name
                 else:
                     continue
@@ -139,12 +139,14 @@ class IndexView(tables.DataTableView):
                 cost = '0'
                 usage = '0'
 
+            latest_price = price_list[-1][1]
+
             result.append( {
                     'name': resource_name,
                     'unit': unit,
                     'value': usage,
                     'id': resource['id'],
-                    'price': '{}/{}'.format(price, cost_unit),
+                    'price': '{}/{}'.format(latest_price, cost_unit),
                     'resource_type': resource['type'],
                     'cost': cost,
                     'flavor': resource_flavor
@@ -158,10 +160,16 @@ class IndexView(tables.DataTableView):
             flavor_name = resource.get('flavor_name', None)
             if not flavor_name: flavor_name = api.nova.flavor_get(request, resource['flavor_id']).name
             flavor = db_session.query(Flavor).filter(Flavor.name == flavor_name).first()
-            price = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').first()
+            row_list = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').all()
         elif resource['type'] == 'volume':
             volume_type = resource['volume_type'] or ''
             volume =  db_session.query(Storage).filter(Storage.volume == volume_type).first()
-            price = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').first()
-            
-        return price.price, price.unit
+            row_list = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').all()
+
+        price_list = []
+        for row in row_list:
+            date = row.since
+            price = row.price
+            price_list.append((date,price))
+
+        return sorted(price_list, key=lambda x: x[0]), row_list[0].unit
diff --git a/charms/garr-dashboard/files/plugins/admin-costs/tables.py b/charms/garr-dashboard/files/plugins/admin-costs/tables.py
index 42762333a4e8d1fd2f9147c1198856d2a770ec99..80ab5708d4e7186692115c58c7e633d063d9f107 100644
--- a/charms/garr-dashboard/files/plugins/admin-costs/tables.py
+++ b/charms/garr-dashboard/files/plugins/admin-costs/tables.py
@@ -1,3 +1,4 @@
+import logging
 from django.contrib.humanize.templatetags import humanize
 from django.utils import text
 from django.utils.translation import ugettext_lazy as _
@@ -12,32 +13,38 @@ from django import forms as django_forms
 from horizon import tables
 from horizon import forms
 
+LOG = logging.getLogger(__name__)
 def get_link(resource):
-    if resource['resource_type'] == 'instance':
+    resource_type = resource.get('resource_type', None)
+    if resource_type == 'instance':
         link =  'horizon:project:instances:detail'
-    elif resource['resource_type'] == 'volume':
+    elif resource_type == 'volume':
         link = 'horizon:project:volumes:detail'
     else:
         return ''
+    try:
+        url = urlresolvers.reverse(link, args=(resource['id'],))
+    except Exception:
+        url = ''
+    return url
 
-    return urlresolvers.reverse(link, args=(resource['id'],))
-
-class CostsTable(tables.DataTable): 
+class CostsTable(tables.DataTable):
     resource = tables.WrappingColumn('name', verbose_name=_('Resource Name'),
                                      link=get_link)
     id = tables.WrappingColumn('id', verbose_name=_('ID'),
                        attrs={'data-type': 'uuid'},
                        hidden=True)
     resource_type = tables.WrappingColumn('resource_type', verbose_name=_('Resource Type'))
-                                 
+
+    flavor = tables.Column('flavor', verbose_name=_("Resource flavor"))
     value = tables.Column('value', verbose_name=_('Usage'))
     unit = tables.Column('unit', verbose_name=_("Unit"))
-    price = tables.Column('price', verbose_name=_("Price"))
+    price = tables.Column('price', verbose_name=_("Latest price"))
     cost = tables.Column('cost', verbose_name=_("Total Cost"))
 
     def get_object_id(self, resource):
         return resource['id']
-    
+
     class Meta(object):
         name = 'costs_table'
         verbose_name = _("Costs")
diff --git a/charms/garr-dashboard/files/plugins/admin-costs/utils.py b/charms/garr-dashboard/files/plugins/admin-costs/utils.py
index ef039b6763b53c71d2ba465c762aa6d8589508c7..84f833d03589c56ba3c9ade687b28b48b774b58d 100644
--- a/charms/garr-dashboard/files/plugins/admin-costs/utils.py
+++ b/charms/garr-dashboard/files/plugins/admin-costs/utils.py
@@ -26,20 +26,14 @@ def get_measure_value(measures, metric, resource):
         result = convert_nanoseconds(result)
     return result
 
-def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_client):
-    unit = 'GB'    
-    try:
-        api.cinder.volume_get(request, resource['id'])
-    except Exception:
-        raise Exception('Volume %s not found' % resource['id'])
-
+def compute_volume_cost(resource, price, start_date, end_date, gnocchi_client):
     measures = [measure[2] for measure in gnocchi_client.metric.get_measures(
-        'volume.size', start=usage_start, stop=usage_end,
+        'volume.size', start=start_date, stop=end_date,
         aggregation='max', resource_id=resource['id']
     )]
 
     if not measures:
-        return 0, 0, unit
+        return 0, 0
 
     usage = sum(measures)/len(measures)
     cost = '{0:.2f}'.format(
@@ -47,22 +41,170 @@ def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_c
         )
     usage = '{0:.2f}'.format(usage)
     
+    return cost, usage
+
+
+def get_volume_usage(request, resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'GB*hour'
+    try:
+        api.cinder.volume_get(request, resource['id'])
+    except Exception:
+        raise Exception('Volume %s not found' % resource['id'])
+
+    cost = '{0:.2f}'.format(0)
+    usage = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_volume_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
     return cost, usage, unit
 
-def get_instance_usage(resource, price, usage_start, usage_end):
-    unit = 'hour'
-    start_time = parse_datetime(resource['started_at']).replace(tzinfo=None)
-    start_query = datetime.strptime(usage_start, "%Y-%m-%d")
-    diff = start_query - start_time
-    
-    hours_interval = get_hours(usage_start, usage_end)
-    if diff.days < 0:
-        end_query = datetime.strptime(usage_end, "%Y-%m-%d")
-        diff = end_query - start_time
-        hours_interval = diff.days * 24
+def compute_instance_cost(resource, price, start_date, end_date, gnocchi_client):
+    cpu_util_measures = gnocchi_client.metric.get_measures(metric=resource['metrics']['cpu_util'],start=start_date,stop=end_date)
+    hours_interval = (len(cpu_util_measures)*5)/60
         
     cost = '{0:.2f}'.format(
         round(hours_interval * price, 2)
         )
 
-    return cost, hours_interval, unit
+    return cost, hours_interval
+
+def get_instance_usage(resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'hour'
+    usage = 0
+    cost = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_instance_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+    return cost, usage, unit
diff --git a/charms/garr-dashboard/files/plugins/admin-costs/views.py b/charms/garr-dashboard/files/plugins/admin-costs/views.py
index 605e61c7b8f48e7dc6fd4c8ca6aa96c2c2a5b6c8..f9079eb1eb571117ecaf0ad80c6bfaa6deb4c0df 100644
--- a/charms/garr-dashboard/files/plugins/admin-costs/views.py
+++ b/charms/garr-dashboard/files/plugins/admin-costs/views.py
@@ -1,141 +1,175 @@
-import logging
-
-from oslo_utils import units
-
-from django.utils.translation import ugettext_lazy as _
-from django.utils import timezone
-from horizon import exceptions
-from horizon import messages
-from horizon import tables
-from horizon import fogitrms
-
-from openstack_dashboard import api
-from openstack_dashboard import policy
-from sqlalchemy.orm import Session
-
-from openstack_dashboard.dashboards.project.costs import tables as costs_tables
-
-from gnocchi import gnocchi_client
-from utils import convert_nanoseconds, get_instance_usage, get_volume_usage
-from orm import engine, Flavor, Price, Storage
-
-LOG = logging.getLogger(__name__)
-
-GARR_DB_KEY = 'GARR_DATABASE'
-
-
-class IndexView(tables.DataTableView):
-    table_class = costs_tables.CostsTable
-    page_title = _("Project Costs")
-    template_name = 'project/costs/index.html'
-
-    def get_context_data(self, **kwargs):
-        context = super(IndexView, self).get_context_data(**kwargs)
-        context['form'] = self.get_form(self.request)
-        context['overall_cost'] = sum(float(row['cost']) for row in context['table'].data)
-        return context
-
-    @staticmethod
-    def get_default_interval():
-        start_time = timezone.now() - timezone.timedelta(days=1)
-        end_time = timezone.now()
-        start = start_time.strftime('%Y-%m-%d')
-        end = end_time.strftime('%Y-%m-%d')
-
-        return start, end
-
-    def get_form(self, request):
-        if not hasattr(self, 'form'):
-            req = request
-            start = req.GET.get('start', None)
-            end = req.GET.get('end', None)
-            if not start and not end:
-                start, end = self.get_default_interval()
-            self.form = forms.DateForm(initial={'start': start, 'end': end})
-        return self.form
-
-    @staticmethod
-    def get_interval(request):
-        usage_start = request.GET.get('start', None)
-        usage_end = request.GET.get('end', None)
-        if not usage_start and not usage_end:
-            usage_start, usage_end = IndexView.get_default_interval()
-
-        return usage_start, usage_end
-
-    def get_data(self):
-        try:
-            session = Session(engine)
-        except Exception as e:
-            LOG.error('Unable to connect to the database')
-            LOG.error(e)
-            return []
-        project_id = self.request.GET.get('project', self.request.user.project_id)
-        query = {
-            "=": {
-                "project_id": project_id
-            }
-        }
-
-        resource_types = ['instance', 'volume']
-        client = gnocchi_client(self.request)
-        project_resources = []
-        for resource_type in resource_types:
-            try:
-                resources = client.resource.search(resource_type=resource_type, query=query, details=True)
-            except Exception:
-                LOG.error('Error while calling gnocchi api')
-                messages.error(self.request, _("Error while calling Gnocchi API"))
-                continue
-
-            project_resources.extend(resources)
-
-        usage_start, usage_end = self.get_interval(self.request)
-        result = []
-        for resource in project_resources:
-            resource_name = resource.get('name', None) or resource.get('display_name', None) or resource['id']
-            try:
-                price, cost_unit = self.get_price(resource, self.request, session)
-            except Exception as e:
-                LOG.error("Unable to fetch price for resource %s of type %s" % (resource_name, resource['type']))
-                continue
-            
-            if type(cost_unit) is set:
-                cost_unit = cost_unit.pop()
-
-            try:
-                if resource['type'] == 'instance': 
-                    cost, usage, unit = get_instance_usage(resource, price, usage_start, usage_end)
-                elif resource['type'] == 'volume':
-                    cost, usage, unit = get_volume_usage(self.request, resource, price, usage_start, usage_end, client)
-                else:
-                    continue
-            except Exception as ex:
-                LOG.error('Unable to get usage for resource %s' % resource)
-                continue
-
-            result.append( {
-                    'name': resource_name,
-                    'unit': unit,
-                    'value': usage,
-                    'id': resource['id'],
-                    'price': '{}/{}'.format(price, cost_unit),
-                    'resource_type': resource['type'],
-                    'cost': cost
-                })
-
-        return sorted(result, key=lambda resource: resource['name'])
-
-
-    def get_price(self, resource, request, db_session):
-        if resource['type'] == 'instance':
-            flavor_name = resource.get('flavor_name', None)
-            if not flavor_name: flavor_name = api.nova.flavor_get(request, resource['flavor_id']).name
-            flavor = db_session.query(Flavor).filter(Flavor.name == flavor_name).first()
-            price = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').first()
-        elif resource['type'] == 'volume':
-            volume_type = resource['volume_type'] or ''
-            volume =  db_session.query(Storage).filter(Storage.volume == volume_type).first()
-            price = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').first()
-            
-        return price.price, price.unit
+import logging
+
+from oslo_utils import units
+
+from django.utils.translation import ugettext_lazy as _
+from django.utils import timezone
+from horizon import exceptions
+from horizon import messages
+from horizon import tables
+from horizon import forms
+
+from openstack_dashboard import api
+from openstack_dashboard import policy
+from sqlalchemy.orm import Session
+
+from openstack_dashboard.dashboards.project.costs import tables as costs_tables
+
+from gnocchi import gnocchi_client
+from utils import convert_nanoseconds, get_instance_usage, get_volume_usage
+from orm import engine, Flavor, Price, Storage
+
+LOG = logging.getLogger(__name__)
+
+GARR_DB_KEY = 'GARR_DATABASE'
+
+
+class IndexView(tables.DataTableView):
+    table_class = costs_tables.CostsTable
+    page_title = _("Project Costs")
+    template_name = 'project/costs/index.html'
+
+    def get_context_data(self, **kwargs):
+        context = super(IndexView, self).get_context_data(**kwargs)
+        context['form'] = self.get_form(self.request)
+        context['overall_cost'] = sum(float(row['cost']) for row in context['table'].data)
+        return context
+
+    @staticmethod
+    def get_default_interval():
+        start_time = timezone.now() - timezone.timedelta(days=1)
+        end_time = timezone.now()
+        start = start_time.strftime('%Y-%m-%d')
+        end = end_time.strftime('%Y-%m-%d')
+
+        return start, end
+
+    def get_form(self, request):
+        if not hasattr(self, 'form'):
+            req = request
+            start = req.GET.get('start', None)
+            end = req.GET.get('end', None)
+            if not start and not end:
+                start, end = self.get_default_interval()
+            self.form = forms.DateForm(initial={'start': start, 'end': end})
+        return self.form
+
+    @staticmethod
+    def get_interval(request):
+        usage_start = request.GET.get('start', None)
+        usage_end = request.GET.get('end', None)
+        if (not usage_start) or (not usage_end) or not (usage_end > usage_start):
+            usage_start, usage_end = IndexView.get_default_interval()
+
+        return usage_start, usage_end
+
+    def get_data(self):
+        try:
+            session = Session(engine)
+        except Exception as e:
+            LOG.error('Unable to connect to the database')
+            LOG.error(e)
+            return []
+
+        query = {
+            "=": {
+                "project_id": self.request.user.project_id
+            }
+        }
+
+        resource_types = ['instance', 'volume']
+        client = gnocchi_client(self.request)
+        project_resources = []
+        for resource_type in resource_types:
+            try:
+                resources = client.resource.search(resource_type=resource_type, query=query, details=True)
+            except Exception:
+                LOG.error('Error while calling gnocchi api')
+                messages.error(self.request, _("Error while calling Gnocchi API"))
+                continue
+
+            project_resources.extend(resources)
+
+        usage_start, usage_end = self.get_interval(self.request)
+        result = []
+        for resource in project_resources:
+            resource_not_in_timeframe = False
+
+            resource_name = resource.get('name', None) or resource.get('display_name', None) or resource['id']
+
+            resource_usage_start = resource['started_at'][:10]
+            if resource['ended_at']:
+                resource_usage_end = resource['ended_at'][:10]
+            else:
+                resource_usage_end = usage_end
+
+            # make sure that the resource existed during this interval
+            if (resource_usage_end < usage_start) or (resource_usage_start > usage_end):
+                resource_not_in_timeframe = True
+
+            # truncate the interval defined by the resource_usage_* variables
+            if not (resource_usage_start > usage_start):
+                resource_usage_start = usage_start
+            if not (resource_usage_end < usage_end):
+                resource_usage_end = usage_end
+
+            try:
+                price_list, cost_unit = self.get_price(resource, self.request, session)
+            except Exception as e:
+                LOG.error("Unable to fetch price for resource %s of type %s" % (resource_name, resource['type']))
+                continue
+            
+            if type(cost_unit) is set:
+                cost_unit = cost_unit.pop()
+
+            try:
+                if resource['type'] == 'instance': 
+                    cost, usage, unit = get_instance_usage(resource, price_list, resource_usage_start, resource_usage_end, client)
+                    resource_flavor = resource['flavor_name']
+                elif resource['type'] == 'volume':
+                    cost, usage, unit = get_volume_usage(self.request, resource, price_list, resource_usage_start, resource_usage_end, client)
+                    resource_flavor = api.cinder.volume_type_get(self.request, resource['volume_type']).name
+                else:
+                    continue
+            except Exception as ex:
+                LOG.error('Unable to get usage for resource %s' % resource)
+                continue
+
+            if resource_not_in_timeframe:
+                cost = '0'
+                usage = '0'
+
+            latest_price = price_list[-1][1]
+
+            result.append( {
+                    'name': resource_name,
+                    'unit': unit,
+                    'value': usage,
+                    'id': resource['id'],
+                    'price': '{}/{}'.format(latest_price, cost_unit),
+                    'resource_type': resource['type'],
+                    'cost': cost,
+                    'flavor': resource_flavor
+                })
+
+        return sorted(result, key=lambda resource: resource['name'])
+
+
+    def get_price(self, resource, request, db_session):
+        if resource['type'] == 'instance':
+            flavor_name = resource.get('flavor_name', None)
+            if not flavor_name: flavor_name = api.nova.flavor_get(request, resource['flavor_id']).name
+            flavor = db_session.query(Flavor).filter(Flavor.name == flavor_name).first()
+            row_list = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').all()
+        elif resource['type'] == 'volume':
+            volume_type = resource['volume_type'] or ''
+            volume =  db_session.query(Storage).filter(Storage.volume == volume_type).first()
+            row_list = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').all()
+
+        price_list = []
+        for row in row_list:
+            date = row.since
+            price = row.price
+            price_list.append((date,price))
+
+        return sorted(price_list, key=lambda x: x[0]), row_list[0].unit
diff --git a/charms/garr-dashboard/files/plugins/project-costs/tables.py b/charms/garr-dashboard/files/plugins/project-costs/tables.py
index aa3ec0e4c36dea930dd1ba8dd2517573e78f9256..80ab5708d4e7186692115c58c7e633d063d9f107 100644
--- a/charms/garr-dashboard/files/plugins/project-costs/tables.py
+++ b/charms/garr-dashboard/files/plugins/project-costs/tables.py
@@ -36,9 +36,10 @@ class CostsTable(tables.DataTable):
                        hidden=True)
     resource_type = tables.WrappingColumn('resource_type', verbose_name=_('Resource Type'))
 
+    flavor = tables.Column('flavor', verbose_name=_("Resource flavor"))
     value = tables.Column('value', verbose_name=_('Usage'))
     unit = tables.Column('unit', verbose_name=_("Unit"))
-    price = tables.Column('price', verbose_name=_("Price"))
+    price = tables.Column('price', verbose_name=_("Latest price"))
     cost = tables.Column('cost', verbose_name=_("Total Cost"))
 
     def get_object_id(self, resource):
@@ -48,4 +49,4 @@ class CostsTable(tables.DataTable):
         name = 'costs_table'
         verbose_name = _("Costs")
         table_actions = ()
-        multi_select = False
\ No newline at end of file
+        multi_select = False
diff --git a/charms/garr-dashboard/files/plugins/project-costs/utils.py b/charms/garr-dashboard/files/plugins/project-costs/utils.py
index ef039b6763b53c71d2ba465c762aa6d8589508c7..84f833d03589c56ba3c9ade687b28b48b774b58d 100644
--- a/charms/garr-dashboard/files/plugins/project-costs/utils.py
+++ b/charms/garr-dashboard/files/plugins/project-costs/utils.py
@@ -26,20 +26,14 @@ def get_measure_value(measures, metric, resource):
         result = convert_nanoseconds(result)
     return result
 
-def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_client):
-    unit = 'GB'    
-    try:
-        api.cinder.volume_get(request, resource['id'])
-    except Exception:
-        raise Exception('Volume %s not found' % resource['id'])
-
+def compute_volume_cost(resource, price, start_date, end_date, gnocchi_client):
     measures = [measure[2] for measure in gnocchi_client.metric.get_measures(
-        'volume.size', start=usage_start, stop=usage_end,
+        'volume.size', start=start_date, stop=end_date,
         aggregation='max', resource_id=resource['id']
     )]
 
     if not measures:
-        return 0, 0, unit
+        return 0, 0
 
     usage = sum(measures)/len(measures)
     cost = '{0:.2f}'.format(
@@ -47,22 +41,170 @@ def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_c
         )
     usage = '{0:.2f}'.format(usage)
     
+    return cost, usage
+
+
+def get_volume_usage(request, resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'GB*hour'
+    try:
+        api.cinder.volume_get(request, resource['id'])
+    except Exception:
+        raise Exception('Volume %s not found' % resource['id'])
+
+    cost = '{0:.2f}'.format(0)
+    usage = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_volume_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
     return cost, usage, unit
 
-def get_instance_usage(resource, price, usage_start, usage_end):
-    unit = 'hour'
-    start_time = parse_datetime(resource['started_at']).replace(tzinfo=None)
-    start_query = datetime.strptime(usage_start, "%Y-%m-%d")
-    diff = start_query - start_time
-    
-    hours_interval = get_hours(usage_start, usage_end)
-    if diff.days < 0:
-        end_query = datetime.strptime(usage_end, "%Y-%m-%d")
-        diff = end_query - start_time
-        hours_interval = diff.days * 24
+def compute_instance_cost(resource, price, start_date, end_date, gnocchi_client):
+    cpu_util_measures = gnocchi_client.metric.get_measures(metric=resource['metrics']['cpu_util'],start=start_date,stop=end_date)
+    hours_interval = (len(cpu_util_measures)*5)/60
         
     cost = '{0:.2f}'.format(
         round(hours_interval * price, 2)
         )
 
-    return cost, hours_interval, unit
+    return cost, hours_interval
+
+def get_instance_usage(resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'hour'
+    usage = 0
+    cost = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_instance_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+    return cost, usage, unit
diff --git a/charms/garr-dashboard/files/plugins/project-costs/views.py b/charms/garr-dashboard/files/plugins/project-costs/views.py
index 6c1c5fc96853a9c87cb43a649c1a7370e4ef7f2e..f9079eb1eb571117ecaf0ad80c6bfaa6deb4c0df 100644
--- a/charms/garr-dashboard/files/plugins/project-costs/views.py
+++ b/charms/garr-dashboard/files/plugins/project-costs/views.py
@@ -58,7 +58,7 @@ class IndexView(tables.DataTableView):
     def get_interval(request):
         usage_start = request.GET.get('start', None)
         usage_end = request.GET.get('end', None)
-        if not usage_start and not usage_end:
+        if (not usage_start) or (not usage_end) or not (usage_end > usage_start):
             usage_start, usage_end = IndexView.get_default_interval()
 
         return usage_start, usage_end
@@ -93,9 +93,28 @@ class IndexView(tables.DataTableView):
         usage_start, usage_end = self.get_interval(self.request)
         result = []
         for resource in project_resources:
+            resource_not_in_timeframe = False
+
             resource_name = resource.get('name', None) or resource.get('display_name', None) or resource['id']
+
+            resource_usage_start = resource['started_at'][:10]
+            if resource['ended_at']:
+                resource_usage_end = resource['ended_at'][:10]
+            else:
+                resource_usage_end = usage_end
+
+            # make sure that the resource existed during this interval
+            if (resource_usage_end < usage_start) or (resource_usage_start > usage_end):
+                resource_not_in_timeframe = True
+
+            # truncate the interval defined by the resource_usage_* variables
+            if not (resource_usage_start > usage_start):
+                resource_usage_start = usage_start
+            if not (resource_usage_end < usage_end):
+                resource_usage_end = usage_end
+
             try:
-                price, cost_unit = self.get_price(resource, self.request, session)
+                price_list, cost_unit = self.get_price(resource, self.request, session)
             except Exception as e:
                 LOG.error("Unable to fetch price for resource %s of type %s" % (resource_name, resource['type']))
                 continue
@@ -105,23 +124,32 @@ class IndexView(tables.DataTableView):
 
             try:
                 if resource['type'] == 'instance': 
-                    cost, usage, unit = get_instance_usage(resource, price, usage_start, usage_end)
+                    cost, usage, unit = get_instance_usage(resource, price_list, resource_usage_start, resource_usage_end, client)
+                    resource_flavor = resource['flavor_name']
                 elif resource['type'] == 'volume':
-                    cost, usage, unit = get_volume_usage(self.request, resource, price, usage_start, usage_end, client)
+                    cost, usage, unit = get_volume_usage(self.request, resource, price_list, resource_usage_start, resource_usage_end, client)
+                    resource_flavor = api.cinder.volume_type_get(self.request, resource['volume_type']).name
                 else:
                     continue
             except Exception as ex:
                 LOG.error('Unable to get usage for resource %s' % resource)
                 continue
 
+            if resource_not_in_timeframe:
+                cost = '0'
+                usage = '0'
+
+            latest_price = price_list[-1][1]
+
             result.append( {
                     'name': resource_name,
                     'unit': unit,
                     'value': usage,
                     'id': resource['id'],
-                    'price': '{}/{}'.format(price, cost_unit),
+                    'price': '{}/{}'.format(latest_price, cost_unit),
                     'resource_type': resource['type'],
-                    'cost': cost
+                    'cost': cost,
+                    'flavor': resource_flavor
                 })
 
         return sorted(result, key=lambda resource: resource['name'])
@@ -132,10 +160,16 @@ class IndexView(tables.DataTableView):
             flavor_name = resource.get('flavor_name', None)
             if not flavor_name: flavor_name = api.nova.flavor_get(request, resource['flavor_id']).name
             flavor = db_session.query(Flavor).filter(Flavor.name == flavor_name).first()
-            price = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').first()
+            row_list = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').all()
         elif resource['type'] == 'volume':
             volume_type = resource['volume_type'] or ''
             volume =  db_session.query(Storage).filter(Storage.volume == volume_type).first()
-            price = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').first()
-            
-        return price.price, price.unit
+            row_list = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').all()
+
+        price_list = []
+        for row in row_list:
+            date = row.since
+            price = row.price
+            price_list.append((date,price))
+
+        return sorted(price_list, key=lambda x: x[0]), row_list[0].unit
diff --git a/costs-plugin/garr_costs/content/costs/tables.py b/costs-plugin/garr_costs/content/costs/tables.py
index 7bc775eb0b94ff096d98133caa64b62108e0a931..80ab5708d4e7186692115c58c7e633d063d9f107 100644
--- a/costs-plugin/garr_costs/content/costs/tables.py
+++ b/costs-plugin/garr_costs/content/costs/tables.py
@@ -39,7 +39,7 @@ class CostsTable(tables.DataTable):
     flavor = tables.Column('flavor', verbose_name=_("Resource flavor"))
     value = tables.Column('value', verbose_name=_('Usage'))
     unit = tables.Column('unit', verbose_name=_("Unit"))
-    price = tables.Column('price', verbose_name=_("Price"))
+    price = tables.Column('price', verbose_name=_("Latest price"))
     cost = tables.Column('cost', verbose_name=_("Total Cost"))
 
     def get_object_id(self, resource):
diff --git a/costs-plugin/garr_costs/content/costs/utils.py b/costs-plugin/garr_costs/content/costs/utils.py
index 0d51798b840cdf9280943abbb3b6750d35edba2d..84f833d03589c56ba3c9ade687b28b48b774b58d 100644
--- a/costs-plugin/garr_costs/content/costs/utils.py
+++ b/costs-plugin/garr_costs/content/costs/utils.py
@@ -26,20 +26,14 @@ def get_measure_value(measures, metric, resource):
         result = convert_nanoseconds(result)
     return result
 
-def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_client):
-    unit = 'GB*hour'
-    try:
-        api.cinder.volume_get(request, resource['id'])
-    except Exception:
-        raise Exception('Volume %s not found' % resource['id'])
-
+def compute_volume_cost(resource, price, start_date, end_date, gnocchi_client):
     measures = [measure[2] for measure in gnocchi_client.metric.get_measures(
-        'volume.size', start=usage_start, stop=usage_end,
+        'volume.size', start=start_date, stop=end_date,
         aggregation='max', resource_id=resource['id']
     )]
 
     if not measures:
-        return 0, 0, unit
+        return 0, 0
 
     usage = sum(measures)/len(measures)
     cost = '{0:.2f}'.format(
@@ -47,16 +41,170 @@ def get_volume_usage(request, resource, price, usage_start, usage_end, gnocchi_c
         )
     usage = '{0:.2f}'.format(usage)
     
-    return cost, usage, unit
+    return cost, usage
 
-def get_instance_usage(resource, price, usage_start, usage_end, gnocchi_client):
-    unit = 'hour'
 
-    cpu_util_measures = gnocchi_client.metric.get_measures(metric=resource['metrics']['cpu_util'],start=usage_start,stop=usage_end)
+def get_volume_usage(request, resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'GB*hour'
+    try:
+        api.cinder.volume_get(request, resource['id'])
+    except Exception:
+        raise Exception('Volume %s not found' % resource['id'])
+
+    cost = '{0:.2f}'.format(0)
+    usage = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_volume_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_volume_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+    return cost, usage, unit
+
+def compute_instance_cost(resource, price, start_date, end_date, gnocchi_client):
+    cpu_util_measures = gnocchi_client.metric.get_measures(metric=resource['metrics']['cpu_util'],start=start_date,stop=end_date)
     hours_interval = (len(cpu_util_measures)*5)/60
         
     cost = '{0:.2f}'.format(
         round(hours_interval * price, 2)
         )
 
-    return cost, hours_interval, unit
+    return cost, hours_interval
+
+def get_instance_usage(resource, price_list, usage_start, usage_end, gnocchi_client):
+    unit = 'hour'
+    usage = 0
+    cost = '{0:.2f}'.format(0)
+
+    if len(price_list)==1:
+        cost, usage = compute_instance_cost(resource, price_list[0][1], usage_start, usage_end, gnocchi_client)
+        return cost, usage, unit
+
+    for i in range(len(price_list)-1):
+        if price_list[i+1][0] < usage_start:
+            #price[i+1] is older than usage_start
+            if i+1 == len(price_list):
+                #price[i+1] is the most recent in the DB though
+                interval_start = usage_start
+                interval_end = usage_end
+                interval_price = price_list[i+1][1]
+
+                interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+                cost = cost + interval_cost
+                usage = usage + interval_usage
+                break
+            else:
+                continue
+
+        if price_list[i][0] > usage_end:
+            #price[i] is newer than usage_end
+            break
+
+        if price_list[i][0] <= usage_start and price_list[i+1][0] > usage_end:
+            #the resource was only used between the dates of price[i] and price[i+1]
+            interval_start=usage_start
+            interval_end=usage_end
+            interval_price=price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+        if price_list[i][0] < usage_start and price_list[i+1][0] > usage_start and price_list[i+1][0] < usage_end:
+            #price[i] is older than usage_start and price[i+1] is newer than usage_start but older than usage_end
+            interval_start = usage_start
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] >= usage_start and price_list[i+1][0] < usage_end:
+            #price[i] and price[i+1] existed between usage_start and usage_end
+            interval_start = price_list[i][0]
+            interval_end = price_list[i+1][0]
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            continue
+
+        if price_list[i][0] < usage_end and price_list[i+1][0] > usage_end and price_list[i][0] > usage_start:
+            #price[i] is older than usage_end while price[i+1] is newer and they're all newer than usage_start
+            interval_start = price_list[i][0]
+            interval_end = usage_end
+            interval_price = price_list[i][1]
+
+            interval_cost, interval_usage = compute_instance_cost(resource, interval_price, interval_start, interval_end, gnocchi_client)
+            cost = cost + interval_cost
+            usage = usage + interval_usage
+            break
+
+    return cost, usage, unit
diff --git a/costs-plugin/garr_costs/content/costs/views.py b/costs-plugin/garr_costs/content/costs/views.py
index 6e7ea6b3478322a756a7eaf149916c36c1b006ec..f9079eb1eb571117ecaf0ad80c6bfaa6deb4c0df 100644
--- a/costs-plugin/garr_costs/content/costs/views.py
+++ b/costs-plugin/garr_costs/content/costs/views.py
@@ -114,7 +114,7 @@ class IndexView(tables.DataTableView):
                 resource_usage_end = usage_end
 
             try:
-                price, cost_unit = self.get_price(resource, self.request, session)
+                price_list, cost_unit = self.get_price(resource, self.request, session)
             except Exception as e:
                 LOG.error("Unable to fetch price for resource %s of type %s" % (resource_name, resource['type']))
                 continue
@@ -124,10 +124,10 @@ class IndexView(tables.DataTableView):
 
             try:
                 if resource['type'] == 'instance': 
-                    cost, usage, unit = get_instance_usage(resource, price, resource_usage_start, resource_usage_end, client)
+                    cost, usage, unit = get_instance_usage(resource, price_list, resource_usage_start, resource_usage_end, client)
                     resource_flavor = resource['flavor_name']
                 elif resource['type'] == 'volume':
-                    cost, usage, unit = get_volume_usage(self.request, resource, price, resource_usage_start, resource_usage_end, client)
+                    cost, usage, unit = get_volume_usage(self.request, resource, price_list, resource_usage_start, resource_usage_end, client)
                     resource_flavor = api.cinder.volume_type_get(self.request, resource['volume_type']).name
                 else:
                     continue
@@ -139,12 +139,14 @@ class IndexView(tables.DataTableView):
                 cost = '0'
                 usage = '0'
 
+            latest_price = price_list[-1][1]
+
             result.append( {
                     'name': resource_name,
                     'unit': unit,
                     'value': usage,
                     'id': resource['id'],
-                    'price': '{}/{}'.format(price, cost_unit),
+                    'price': '{}/{}'.format(latest_price, cost_unit),
                     'resource_type': resource['type'],
                     'cost': cost,
                     'flavor': resource_flavor
@@ -158,10 +160,16 @@ class IndexView(tables.DataTableView):
             flavor_name = resource.get('flavor_name', None)
             if not flavor_name: flavor_name = api.nova.flavor_get(request, resource['flavor_id']).name
             flavor = db_session.query(Flavor).filter(Flavor.name == flavor_name).first()
-            price = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').first()
+            row_list = db_session.query(Price).filter(Price.resource == flavor.id, Price.type == 'flavor').all()
         elif resource['type'] == 'volume':
             volume_type = resource['volume_type'] or ''
             volume =  db_session.query(Storage).filter(Storage.volume == volume_type).first()
-            price = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').first()
-            
-        return price.price, price.unit
+            row_list = db_session.query(Price).filter(Price.resource == volume.id, Price.type == 'storage').all()
+
+        price_list = []
+        for row in row_list:
+            date = row.since
+            price = row.price
+            price_list.append((date,price))
+
+        return sorted(price_list, key=lambda x: x[0]), row_list[0].unit