feat(billing): subscription creation handler (sale.order is_subscription)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-27 02:59:17 -04:00
parent 2435096f32
commit 0754d0b101
2 changed files with 43 additions and 0 deletions

View File

@@ -93,3 +93,30 @@ class FusionBillingService(models.Model):
'included_quota': c.included_quota, 'price_per_unit': c.price_per_unit,
'unit_batch': c.unit_batch, 'charge_model': c.charge_model,
} for c in charges]}
def _api_create_subscription(self, payload):
"""Create and confirm a subscription sale.order for an external customer.
The product on each line must have recurring_invoice=True so that
Odoo recognises the order as a subscription with has_recurring_line and
action_confirm() reaches subscription_state='3_progress'.
"""
self.ensure_one()
link = self.env['fusion.billing.account.link'].search([
('service_id', '=', self.id),
('external_id', '=', payload.get('external_customer_id')),
], limit=1)
if not link:
return {'status': 'error', 'error': 'unknown customer'}
order_lines = [(0, 0, {
'product_id': line['product_id'],
'product_uom_qty': line.get('quantity', 1),
}) for line in payload.get('lines', [])]
sub = self.env['sale.order'].sudo().create({
'partner_id': link.partner_id.id,
'plan_id': payload['plan_id'],
'order_line': order_lines,
})
sub.action_confirm()
return {'status': 'ok', 'subscription_id': sub.id,
'subscription_state': sub.subscription_state}

View File

@@ -45,3 +45,19 @@ class TestApiHandlers(TransactionCase):
cat = self.service._api_catalog()
codes = [c['plan_code'] for c in cat['charges']]
self.assertIn('maps-business', codes)
def test_api_create_subscription(self):
self.service._api_upsert_customer({'external_id': 'client-9', 'name': 'Globex'})
product = self.env['product.product'].sudo().create(
{'name': 'Maps Business', 'type': 'service', 'recurring_invoice': True,
'list_price': 249.0})
res = self.service._api_create_subscription({
'external_customer_id': 'client-9',
'plan_id': self.plan.id,
'lines': [{'product_id': product.id, 'quantity': 1}],
})
self.assertEqual(res['status'], 'ok')
sub = self.env['sale.order'].browse(res['subscription_id'])
self.assertTrue(sub.is_subscription)
self.assertEqual(sub.plan_id, self.plan)
self.assertEqual(sub.subscription_state, '3_progress')