Merge "Trivial fix for odoo driver"
This commit is contained in:
commit
864040f862
|
@ -47,3 +47,6 @@ states = {'active': 1,
|
|||
'error': 10,
|
||||
'shelved': 11,
|
||||
'shelved_offloaded': 12}
|
||||
|
||||
RATE_DIGITS = 6
|
||||
PRICE_DIGITS = 2
|
||||
|
|
|
@ -21,6 +21,7 @@ import odoorpc
|
|||
from oslo_log import log
|
||||
|
||||
from distil.common import cache
|
||||
from distil.common import constants
|
||||
from distil.common import general
|
||||
from distil.common import openstack
|
||||
from distil.erp import driver
|
||||
|
@ -122,7 +123,8 @@ class OdooDriver(driver.BaseDriver):
|
|||
|
||||
self.product_catagory_mapping[product['id']] = category
|
||||
|
||||
price = round(product['lst_price'], 5)
|
||||
rate = round(product['lst_price'],
|
||||
constants.RATE_DIGITS)
|
||||
# NOTE(flwang): default_code is Internal Reference on
|
||||
# Odoo GUI
|
||||
unit = product['default_code']
|
||||
|
@ -130,7 +132,7 @@ class OdooDriver(driver.BaseDriver):
|
|||
|
||||
prices[actual_region][category.lower()].append(
|
||||
{'name': name,
|
||||
'price': price,
|
||||
'rate': rate,
|
||||
'unit': unit,
|
||||
'description': desc}
|
||||
)
|
||||
|
@ -157,7 +159,8 @@ class OdooDriver(driver.BaseDriver):
|
|||
|
||||
prices[actual_region]['object storage'].append(
|
||||
{'name': obj_s_name,
|
||||
'price': round(obj_p.lst_price, 5),
|
||||
'rate': round(obj_p.lst_price,
|
||||
constants.RATE_DIGITS),
|
||||
'unit': obj_p.default_code,
|
||||
'description': obj_p.description}
|
||||
)
|
||||
|
@ -208,9 +211,9 @@ class OdooDriver(driver.BaseDriver):
|
|||
line_info = {
|
||||
'resource_name': line['name'],
|
||||
'quantity': line['quantity'],
|
||||
'rate': line['price_unit'],
|
||||
'rate': round(line['price_unit'], constants.RATE_DIGITS),
|
||||
'unit': line['uos_id'][1],
|
||||
'cost': round(line['price_subtotal'], 2)
|
||||
'cost': round(line['price_subtotal'], constants.PRICE_DIGITS)
|
||||
}
|
||||
|
||||
# Original product is a string like "[hour] NZ-POR-1.c1.c2r8"
|
||||
|
@ -223,7 +226,10 @@ class OdooDriver(driver.BaseDriver):
|
|||
'breakdown': collections.defaultdict(list)
|
||||
}
|
||||
|
||||
detail_dict[catagory]['total_cost'] += line_info['cost']
|
||||
detail_dict[catagory]['total_cost'] = round(
|
||||
(detail_dict[catagory]['total_cost'] + line_info['cost']),
|
||||
constants.PRICE_DIGITS
|
||||
)
|
||||
detail_dict[catagory]['breakdown'][product].append(line_info)
|
||||
|
||||
return detail_dict
|
||||
|
@ -283,7 +289,8 @@ class OdooDriver(driver.BaseDriver):
|
|||
)
|
||||
for v in invoices:
|
||||
result[v['date_invoice']] = {
|
||||
'total_cost': round(v['amount_total'], 2)
|
||||
'total_cost': round(
|
||||
v['amount_total'], constants.PRICE_DIGITS)
|
||||
}
|
||||
|
||||
if detailed:
|
||||
|
@ -328,14 +335,14 @@ class OdooDriver(driver.BaseDriver):
|
|||
if service_type in products:
|
||||
for s in products[service_type]:
|
||||
if s['name'] == service_name:
|
||||
price.update({'rate': s['price'], 'unit': s['unit']})
|
||||
price.update({'rate': s['rate'], 'unit': s['unit']})
|
||||
break
|
||||
else:
|
||||
found = False
|
||||
for category, services in products.items():
|
||||
for s in services:
|
||||
if s['name'] == service_name:
|
||||
price.update({'rate': s['price'], 'unit': s['unit']})
|
||||
price.update({'rate': s['rate'], 'unit': s['unit']})
|
||||
found = True
|
||||
break
|
||||
|
||||
|
@ -407,7 +414,8 @@ class OdooDriver(driver.BaseDriver):
|
|||
|
||||
# Convert volume according to unit in price definition.
|
||||
volume = general.convert_to(volume, unit, price_spec['unit'])
|
||||
cost = (round(volume * Decimal(price_spec['rate']), 2)
|
||||
cost = (round(volume * Decimal(price_spec['rate']),
|
||||
constants.PRICE_DIGITS)
|
||||
if price_spec['rate'] else 0)
|
||||
|
||||
total_cost += cost
|
||||
|
@ -415,7 +423,10 @@ class OdooDriver(driver.BaseDriver):
|
|||
if detailed:
|
||||
odoo_service_name = "%s.%s" % (odoo_region, service_name)
|
||||
|
||||
cost_details[service_type]['total_cost'] += cost
|
||||
cost_details[service_type]['total_cost'] = round(
|
||||
(cost_details[service_type]['total_cost'] + cost),
|
||||
constants.PRICE_DIGITS
|
||||
)
|
||||
cost_details[service_type]['breakdown'][
|
||||
odoo_service_name
|
||||
].append(
|
||||
|
@ -423,13 +434,14 @@ class OdooDriver(driver.BaseDriver):
|
|||
"resource_name": resources[res_id].get('name', ''),
|
||||
"resource_id": res_id,
|
||||
"cost": cost,
|
||||
"quantity": round(volume, 4),
|
||||
"rate": price_spec['rate'],
|
||||
"quantity": round(volume, 3),
|
||||
"rate": round(price_spec['rate'],
|
||||
constants.RATE_DIGITS),
|
||||
"unit": price_spec['unit'],
|
||||
}
|
||||
)
|
||||
|
||||
result = {'total_cost': round(total_cost, 2)}
|
||||
result = {'total_cost': round(total_cost, constants.PRICE_DIGITS)}
|
||||
if detailed:
|
||||
result.update({'details': cost_details})
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ class TestOdooDriver(base.DistilTestCase):
|
|||
|
||||
@mock.patch('odoorpc.ODOO')
|
||||
def test_get_products(self, mock_odoo):
|
||||
|
||||
odoodriver = odoo.OdooDriver(self.conf)
|
||||
odoodriver.product.search.return_value = []
|
||||
odoodriver.product.read.return_value = PRODUCTS
|
||||
|
@ -67,15 +66,15 @@ class TestOdooDriver(base.DistilTestCase):
|
|||
{
|
||||
'nz_1': {
|
||||
'block storage': [{'description': 'Block storage',
|
||||
'price': 0.00035,
|
||||
'rate': 0.00035,
|
||||
'name': 'b1.volume',
|
||||
'unit': 'hour'}],
|
||||
'compute': [{'description': '1 CPU, 1GB RAM',
|
||||
'price': 0.00015,
|
||||
'rate': 0.00015,
|
||||
'name': 'c1.c1r1',
|
||||
'unit': 'hour'}],
|
||||
'network': [{'description': 'Router',
|
||||
'price': 0.00025,
|
||||
'rate': 0.00025,
|
||||
'name': 'n1.router',
|
||||
'unit': 'hour'}]
|
||||
}
|
||||
|
@ -119,29 +118,44 @@ class TestOdooDriver(base.DistilTestCase):
|
|||
[
|
||||
{
|
||||
'name': 'resource1',
|
||||
'quantity': 100,
|
||||
'price_unit': 0.01,
|
||||
'quantity': 1,
|
||||
'price_unit': 0.123,
|
||||
'uos_id': [1, 'Gigabyte-hour(s)'],
|
||||
'price_subtotal': 10,
|
||||
'price_subtotal': 0.123,
|
||||
'product_id': [1, '[hour] NZ-POR-1.c1.c2r8']
|
||||
},
|
||||
{
|
||||
'name': 'resource2',
|
||||
'quantity': 2,
|
||||
'price_unit': 0.123,
|
||||
'uos_id': [1, 'Gigabyte-hour(s)'],
|
||||
'price_subtotal': 0.246,
|
||||
'product_id': [1, '[hour] NZ-POR-1.c1.c2r8']
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
'name': 'resource2',
|
||||
'quantity': 200,
|
||||
'price_unit': 0.01,
|
||||
'name': 'resource3',
|
||||
'quantity': 3,
|
||||
'price_unit': 0.123,
|
||||
'uos_id': [1, 'Gigabyte-hour(s)'],
|
||||
'price_subtotal': 20,
|
||||
'price_subtotal': 0.369,
|
||||
'product_id': [1, '[hour] NZ-POR-1.c1.c2r8']
|
||||
},
|
||||
{
|
||||
'name': 'resource4',
|
||||
'quantity': 4,
|
||||
'price_unit': 0.123,
|
||||
'uos_id': [1, 'Gigabyte-hour(s)'],
|
||||
'price_subtotal': 0.492,
|
||||
'product_id': [1, '[hour] NZ-POR-1.c1.c2r8']
|
||||
}
|
||||
]
|
||||
]
|
||||
odoodriver.odoo.execute.return_value = [
|
||||
{'id': 1, 'date_invoice': '2017-03-31', 'amount_total': 10},
|
||||
{'id': 2, 'date_invoice': '2017-04-30', 'amount_total': 20}
|
||||
{'id': 1, 'date_invoice': '2017-03-31', 'amount_total': 0.371},
|
||||
{'id': 2, 'date_invoice': '2017-04-30', 'amount_total': 0.859}
|
||||
]
|
||||
|
||||
odoodriver.product_catagory_mapping = {
|
||||
1: 'Compute'
|
||||
}
|
||||
|
@ -150,38 +164,58 @@ class TestOdooDriver(base.DistilTestCase):
|
|||
start, end, fake_project, detailed=True
|
||||
)
|
||||
|
||||
# The category total price is get from odoo. The total price of
|
||||
# specific product is calculated based on invoice detail in odoo.
|
||||
self.assertEqual(
|
||||
{
|
||||
'2017-03-31': {
|
||||
'total_cost': 10,
|
||||
'total_cost': 0.37,
|
||||
'details': {
|
||||
'Compute': {
|
||||
'total_cost': 10,
|
||||
'total_cost': 0.37,
|
||||
'breakdown': {
|
||||
'NZ-POR-1.c1.c2r8': [{
|
||||
"cost": 10,
|
||||
"quantity": 100,
|
||||
"rate": 0.01,
|
||||
"resource_name": "resource1",
|
||||
"unit": "Gigabyte-hour(s)"
|
||||
}]
|
||||
'NZ-POR-1.c1.c2r8': [
|
||||
{
|
||||
"cost": 0.12,
|
||||
"quantity": 1,
|
||||
"rate": 0.123,
|
||||
"resource_name": "resource1",
|
||||
"unit": "Gigabyte-hour(s)"
|
||||
},
|
||||
{
|
||||
"cost": 0.25,
|
||||
"quantity": 2,
|
||||
"rate": 0.123,
|
||||
"resource_name": "resource2",
|
||||
"unit": "Gigabyte-hour(s)"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'2017-04-30': {
|
||||
'total_cost': 20,
|
||||
'total_cost': 0.86,
|
||||
'details': {
|
||||
'Compute': {
|
||||
'total_cost': 20,
|
||||
'total_cost': 0.86,
|
||||
'breakdown': {
|
||||
'NZ-POR-1.c1.c2r8': [{
|
||||
"cost": 20,
|
||||
"quantity": 200,
|
||||
"rate": 0.01,
|
||||
"resource_name": "resource2",
|
||||
"unit": "Gigabyte-hour(s)"
|
||||
}]
|
||||
'NZ-POR-1.c1.c2r8': [
|
||||
{
|
||||
"cost": 0.37,
|
||||
"quantity": 3,
|
||||
"rate": 0.123,
|
||||
"resource_name": "resource3",
|
||||
"unit": "Gigabyte-hour(s)"
|
||||
},
|
||||
{
|
||||
"cost": 0.49,
|
||||
"quantity": 4,
|
||||
"rate": 0.123,
|
||||
"resource_name": "resource4",
|
||||
"unit": "Gigabyte-hour(s)"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,13 +233,13 @@ class TestOdooDriver(base.DistilTestCase):
|
|||
'Compute': [
|
||||
{
|
||||
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
||||
'price': 0.01, 'unit': 'hour'
|
||||
'rate': 0.01, 'unit': 'hour'
|
||||
}
|
||||
],
|
||||
'Block Storage': [
|
||||
{
|
||||
'name': 'b1.standard', 'description': 'b1.standard',
|
||||
'price': 0.02, 'unit': 'gigabyte'
|
||||
'rate': 0.02, 'unit': 'gigabyte'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -255,13 +289,13 @@ class TestOdooDriver(base.DistilTestCase):
|
|||
'Compute': [
|
||||
{
|
||||
'name': 'c1.c2r16', 'description': 'c1.c2r16',
|
||||
'price': 0.01, 'unit': 'hour'
|
||||
'rate': 0.01, 'unit': 'hour'
|
||||
}
|
||||
],
|
||||
'Block Storage': [
|
||||
{
|
||||
'name': 'b1.standard', 'description': 'b1.standard',
|
||||
'price': 0.02, 'unit': 'gigabyte'
|
||||
'rate': 0.02, 'unit': 'gigabyte'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -338,7 +372,7 @@ class TestOdooDriver(base.DistilTestCase):
|
|||
)
|
||||
|
||||
@mock.patch('odoorpc.ODOO')
|
||||
def test_get_credits(self, mock_odoo):
|
||||
def test_get_credits(self, mock_odoo):
|
||||
fake_credits = [{'create_uid': [182, 'OpenStack Testing'],
|
||||
'initial_balance': 500.0,
|
||||
'code': '3dd294588f15404f8d77bd97e653324b',
|
||||
|
|
Loading…
Reference in New Issue