fix(billing): reconciliation review fixes — per-subscription key, IDOR guard
- CRITICAL: reconciliation upsert keyed on (service, partner, period) collided when one customer has two deployments (two subs) in a period — the second overwrote the first. Add external_subscription_id to the model + a UNIQUE(service_id, external_subscription_id, period) constraint, and key the upsert per subscription. New test proves two subs for one partner keep two rows. - raise a clear error if the nexacloud service is missing (was a confusing per-row failure). - _fc_resolve_subscription: the integer fallback no longer reaches a different service's tagged subscription (latent multi-service IDOR); live untagged subs stay resolvable and the partner-link authz is unchanged. Full suite green on odoo-trial.
This commit is contained in:
@@ -89,3 +89,23 @@ class TestReconcileRows(TransactionCase):
|
||||
{'subscription_external_id': 'nope', 'period': '2026-05',
|
||||
'cpu_seconds': 0.0, 'external_amount': 1.0}])
|
||||
self.assertTrue(any(s['id'] == 'nope' for s in summary['skipped']))
|
||||
|
||||
def test_two_subscriptions_same_partner_period_do_not_collide(self):
|
||||
# A customer with two deployments -> two subscriptions in the same period.
|
||||
data = _fixture()
|
||||
data['subscriptions'].append(
|
||||
{"id": "s-1b", "user_id": "u-1", "deployment_id": "d-1b", "plan_id": "p-1",
|
||||
"status": "active", "billing_cycle": "monthly",
|
||||
"current_period_start": "2026-05-01", "current_period_end": "2026-06-01"})
|
||||
self.env['fusion.billing.import.wizard'].sudo()._import_rows(data)
|
||||
self.Recon._reconcile_rows([
|
||||
{'subscription_external_id': 's-1', 'period': '2026-05',
|
||||
'cpu_seconds': 0.0, 'external_amount': 20.0},
|
||||
{'subscription_external_id': 's-1b', 'period': '2026-05',
|
||||
'cpu_seconds': 0.0, 'external_amount': 99.0},
|
||||
])
|
||||
partner = self._partner_of('s-1')
|
||||
rows = self.Recon.search(
|
||||
[('partner_id', '=', partner.id), ('period', '=', '2026-05')])
|
||||
self.assertEqual(len(rows), 2, "two subs for one partner must keep two rows")
|
||||
self.assertEqual(set(rows.mapped('external_subscription_id')), {'s-1', 's-1b'})
|
||||
|
||||
Reference in New Issue
Block a user