feat(billing): /usage resolves subscription by source app id (enables 2b)
_api_record_usage now resolves the target subscription via the source app's own id (x_fc_nexacloud_subscription_id, scoped to the service) before falling back to a direct Odoo sale.order id. This is what lets NexaCloud push usage against the shadow subscriptions the importer created from NexaCloud UUIDs — closing the flip-day mapping gap the review flagged. Authz unchanged (partner must be linked to the service).
This commit is contained in:
@@ -254,3 +254,26 @@ class TestImporterReadGuard(TransactionCase):
|
||||
wiz = self.env['fusion.billing.import.wizard'].sudo().create({'dry_run': True})
|
||||
with self.assertRaises(UserError):
|
||||
wiz.action_test_connection()
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestUsageApiSourceId(TransactionCase):
|
||||
"""The /usage API must resolve a subscription by NexaCloud's OWN id, so usage can be
|
||||
pushed against shadow subs the importer created from UUIDs (the flip-day gap)."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.env['fusion.billing.import.wizard'].sudo()._import_rows(_fixture())
|
||||
self.service = self.env['fusion.billing.service'].search([('code', '=', 'nexacloud')])
|
||||
|
||||
def test_record_usage_resolves_by_nexacloud_subscription_id(self):
|
||||
res = self.service._api_record_usage({'events': [{
|
||||
'subscription_external_id': 's-1', # NexaCloud UUID, not the Odoo id
|
||||
'metric_code': 'cpu_seconds', 'quantity': 3600.0,
|
||||
'period_start': '2026-05-01', 'period_end': '2026-06-01',
|
||||
'idempotency_key': 'nc:s-1:2026-05'}]})
|
||||
self.assertEqual(res['status'], 'ok')
|
||||
self.assertEqual(res['accepted'], 1)
|
||||
sub = self.env['sale.order'].search([('x_fc_nexacloud_subscription_id', '=', 's-1')])
|
||||
usage = self.env['fusion.billing.usage'].search([('subscription_id', '=', sub.id)])
|
||||
self.assertEqual(usage.quantity, 3600.0)
|
||||
|
||||
Reference in New Issue
Block a user