Repository: softlayer/softlayer-python
Pull request #1780 (2022-10-26 19:58:48)

Match `virtual detail --prices` option with `hardware detail --prices` option
Issue: https://github.com/softlayer/softlayer-python/issues/1777
Observations: `--price` option was updated to display items and the unit tests were updated
```
slcli vs detail 109648788 --price
┌────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│               name │ value                                                                                                                                                            │
├────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│                 id │ 109648788                                                                                                                                                        │
│               guid │ ddd2f2b8-5f65-4159-8f8f-532d0b275ee3                                                                                                                             │
│           hostname │ techsupport                                                                                                                                                      │
│             domain │ SoftLayer-Internal-Development-Community.cloud                                                                                                                   │
│               fqdn │ techsupport.SoftLayer-Internal-Development-Community.cloud                                                                                                       │
│             status │ Active                                                                                                                                                           │
│              state │ Running                                                                                                                                                          │
│ active_transaction │ -                                                                                                                                                                │
│         datacenter │ sao01                                                                                                                                                            │
│                 os │ CentOS                                                                                                                                                           │
│         os_version │ 8.0-64 Minimal for VSI                                                                                                                                           │
│              cores │ 2                                                                                                                                                                │
│             memory │ 4G                                                                                                                                                               │
│             drives │ ┌────────┬──────┬───────┬──────────┐                                                                                                                             │
│                    │ │  Type  │ Name │ Drive │ Capacity │                                                                                                                             │
│                    │ ├────────┼──────┼───────┼──────────┤                                                                                                                             │
│                    │ │ System │ Disk │   0   │  25 GB   │                                                                                                                             │
│                    │ │  Swap  │ Disk │   1   │   2 GB   │                                                                                                                             │
│                    │ │ System │ Disk │   2   │  10 GB   │                                                                                                                             │
│                    │ │ System │ Disk │   7   │  64 MB   │                                                                                                                             │
│                    │ └────────┴──────┴───────┴──────────┘                                                                                                                             │
│          public_ip │ 169.57.227.67                                                                                                                                                    │
│         private_ip │ 10.151.109.245                                                                                                                                                   │
│       private_only │ False                                                                                                                                                            │
│        private_cpu │ False                                                                                                                                                            │
│          transient │ False                                                                                                                                                            │
│            created │ 2020-09-25T09:34:12-06:00                                                                                                                                        │
│           modified │ 2022-01-25T14:06:54-06:00                                                                                                                                        │
│   last_transaction │ Cloud Migrate (2021-11-30 20:04)                                                                                                                                 │
│            billing │ Hourly                                                                                                                                                           │
│             preset │ B1_2X4X25                                                                                                                                                        │
│              owner │ sl307608-dcabero                                                                                                                                                 │
│              vlans │ ┌─────────┬────────┬─────────┐                                                                                                                                   │
│                    │ │  type   │ number │   id    │                                                                                                                                   │
│                    │ ├─────────┼────────┼─────────┤                                                                                                                                   │
│                    │ │ PRIVATE │  1988  │ 2956450 │                                                                                                                                   │
│                    │ │ PUBLIC  │  1697  │ 2956448 │                                                                                                                                   │
│                    │ └─────────┴────────┴─────────┘                                                                                                                                   │
│          Bandwidth │ ┌─────────┬───────┬────────┬───────────┐                                                                                                                         │
│                    │ │  Type   │ In GB │ Out GB │ Allotment │                                                                                                                         │
│                    │ ├─────────┼───────┼────────┼───────────┤                                                                                                                         │
│                    │ │ Public  │   0   │   0    │     0     │                                                                                                                         │
│                    │ │ Private │   0   │   0    │    N/A    │                                                                                                                         │
│                    │ └─────────┴───────┴────────┴───────────┘                                                                                                                         │
│              notes │ -                                                                                                                                                                │
│             Prices │ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────┬─────────────────┐ │
│                    │ │                                                          Item                                                           │   CategoryCode   │ Recurring Price │ │
│                    │ ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────┼─────────────────┤ │
│                    │ │                                                          Total                                                          │        -         │      75.89      │ │
│                    │ │                                         CentOS 8.x Usage is 743.9997 hours Used                                         │     os_usage     │        0        │ │
│                    │ │ Public & Private Network Uplinks: a suspendable product. Anticipated usage for the billing cycle is 743.9997 hours Used │ port_speed_usage │        0        │ │
│                    │ │            Host Ping: a suspendable product. Anticipated usage for the billing cycle is 743.9997 hours Used             │ monitoring_usage │        0        │ │
│                    │ │            CPU Cores: a suspendable product. Anticipated usage for the billing cycle is 743.9997 hours Used             │ guest_core_usage │      59.52      │ │
│                    │ │      Automated Notification: a suspendable product. Anticipated usage for the billing cycle is 743.9997 hours Used      │  response_usage  │        0        │ │
│                    │ │               4 GB: a suspendable product. Anticipated usage for the billing cycle is 743.9997 hours Used               │    ram_usage     │      16.37      │ │
│                    │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────┴─────────────────┘ │
│         Price rate │ 151.78                                                                                                                                                           │
│               tags │ -                                                                                                                                                                │
└────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```


Patch:
diff --git a/SoftLayer/CLI/virt/detail.py b/SoftLayer/CLI/virt/detail.py
index 4c6ddf73..022e421a 100644
--- a/SoftLayer/CLI/virt/detail.py
+++ b/SoftLayer/CLI/virt/detail.py
@@ -97,12 +97,9 @@ def cli(env, identifier, passwords=False, price=False):
         total_price = utils.lookup(result,
                                    'billingItem',
                                    'nextInvoiceTotalRecurringAmount') or 0
-        total_price += sum(p['nextInvoiceTotalRecurringAmount']
-                           for p
-                           in utils.lookup(result,
-                                           'billingItem',
-                                           'children') or [])
-        table.add_row(['price_rate', total_price])
+        if total_price != 0:
+            table.add_row(['Prices', _price_table(utils.lookup(result, 'billingItem'), total_price)])
+            table.add_row(['Price rate', total_price])
 
     if passwords:
         pass_table = formatting.Table(['software', 'username', 'password'])
@@ -156,6 +153,17 @@ def _bw_table(bw_data):
     return table
 
 
+def _price_table(billing_item, total_price):
+    """Returns an item table"""
+    price_table = formatting.Table(['Item', 'CategoryCode', 'Recurring Price'])
+    price_table.add_row(['Total', '-', total_price])
+    items = billing_item['nextInvoiceChildren']
+    for item in items:
+        if item.get('recurringFee') is not None:
+            price_table.add_row([item['description'], item['categoryCode'], item['recurringFee']])
+    return price_table
+
+
 def _cli_helper_dedicated_host(env, result, table):
     """Get details on dedicated host for a virtual server."""
 
diff --git a/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py b/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py
index aab22b5e..6ca56d77 100644
--- a/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py
+++ b/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py
@@ -34,6 +34,60 @@
                 'nextInvoiceTotalRecurringAmount': 1
             }
         ],
+        "nextInvoiceChildren": [
+            {
+                "allowCancellationFlag": 1,
+                "associatedBillingItemId": "738974962",
+                "cancellationDate": "2022-11-03T23:00:01-06:00",
+                "categoryCode": "os_usage",
+                "createDate": "2022-10-04T17:00:08-06:00",
+                "cycleStartDate": "2022-10-04T17:00:08-06:00",
+                "description": "CentOS 8.x Usage is 743.9997 hours Used",
+                "id": 999303609,
+                "laborFee": "0",
+                "laborFeeTaxRate": "0",
+                "lastBillDate": None,
+                "modifyDate": None,
+                "nextBillDate": "2022-11-03T23:00:00-06:00",
+                "oneTimeFee": "0",
+                "oneTimeFeeTaxRate": "0",
+                "orderItemId": None,
+                "parentId": None,
+                "recurringFee": "0",
+                "recurringFeeTaxRate": "0",
+                "recurringMonths": 1,
+                "serviceProviderId": 1,
+                "setupFee": "0",
+                "setupFeeTaxRate": "0",
+                "associatedBillingItem": None
+            },
+            {
+                "allowCancellationFlag": 1,
+                "associatedBillingItemId": "738974962",
+                "cancellationDate": "2022-11-03T23:00:01-06:00",
+                "categoryCode": "guest_core_usage",
+                "createDate": "2022-10-04T17:00:09-06:00",
+                "cycleStartDate": "2022-10-04T17:00:09-06:00",
+                "description": "CPU Cores: a suspendable product.",
+                "id": 999303621,
+                "laborFee": "0",
+                "laborFeeTaxRate": "0",
+                "lastBillDate": None,
+                "modifyDate": None,
+                "nextBillDate": "2022-11-03T23:00:00-06:00",
+                "oneTimeFee": "0",
+                "oneTimeFeeTaxRate": "0",
+                "orderItemId": None,
+                "parentId": None,
+                "recurringFee": "1.54",
+                "recurringFeeTaxRate": "0",
+                "recurringMonths": 1,
+                "serviceProviderId": 1,
+                "setupFee": "0",
+                "setupFeeTaxRate": "0",
+                "associatedBillingItem": None
+            },
+        ],
         'package': {
             "id": 835,
             "keyName": "PUBLIC_CLOUD_SERVER"
diff --git a/SoftLayer/managers/vs.py b/SoftLayer/managers/vs.py
index 06847d42..90cf4bf4 100644
--- a/SoftLayer/managers/vs.py
+++ b/SoftLayer/managers/vs.py
@@ -246,6 +246,10 @@ def get_instance(self, instance_id, **kwargs):
                 '''billingItem[id,nextInvoiceTotalRecurringAmount,
                                package[id,keyName],
                                children[description,categoryCode,nextInvoiceTotalRecurringAmount],
+                               nextInvoiceChildren[description,
+                                                   categoryCode,
+                                                   recurringFee,
+                                                   nextInvoiceTotalRecurringAmount],
                                orderItem[id,
                                          order.userRecord[username],
                                          preset.keyName]],'''


Test patch:
diff --git a/tests/CLI/modules/vs/vs_tests.py b/tests/CLI/modules/vs/vs_tests.py
index 1546af49..13a04fa6 100644
--- a/tests/CLI/modules/vs/vs_tests.py
+++ b/tests/CLI/modules/vs/vs_tests.py
@@ -167,7 +167,7 @@ def test_detail_vs(self):
         self.assert_no_fail(result)
         output = json.loads(result.output)
         self.assertEqual(output['notes'], 'notes')
-        self.assertEqual(output['price_rate'], 6.54)
+        self.assertEqual(output['Price rate'], 1.54)
         self.assertEqual(output['users'][0]['username'], 'user')
         self.assertEqual(output['vlans'][0]['number'], 23)
         self.assertEqual(output['owner'], 'chechu')