parent
819e13481e
commit
6443582c0e
5 changed files with 87 additions and 12 deletions
|
|
@ -108,16 +108,19 @@ class OSBServiceInstanceView(OSBBasicAuthPermission, View):
|
|||
if service in organization.limit_osb_services.all():
|
||||
return JsonResponse({"message": "Service already enabled"}, status=200)
|
||||
except Organization.DoesNotExist:
|
||||
odoo_data = {
|
||||
"company_name": organization_display_name,
|
||||
"invoice_email": user.email,
|
||||
}
|
||||
with transaction.atomic():
|
||||
try:
|
||||
billing_entity = BillingEntity.create_from_data(
|
||||
name=f"{organization_display_name} (Exoscale)",
|
||||
odoo_data=odoo_data,
|
||||
)
|
||||
try:
|
||||
with transaction.atomic():
|
||||
if exoscale_origin.billing_entity:
|
||||
billing_entity = exoscale_origin.billing_entity
|
||||
else:
|
||||
odoo_data = {
|
||||
"company_name": organization_display_name,
|
||||
"invoice_email": user.email,
|
||||
}
|
||||
billing_entity = BillingEntity.create_from_data(
|
||||
name=f"{organization_display_name} (Exoscale)",
|
||||
odoo_data=odoo_data,
|
||||
)
|
||||
organization = Organization(
|
||||
name=organization_display_name,
|
||||
billing_entity=billing_entity,
|
||||
|
|
@ -126,8 +129,8 @@ class OSBServiceInstanceView(OSBBasicAuthPermission, View):
|
|||
)
|
||||
organization = Organization.create_organization(organization, user)
|
||||
self._send_invitation_email(request, organization, user)
|
||||
except Exception:
|
||||
return JsonResponse({"error": "Internal server error"}, status=500)
|
||||
except Exception:
|
||||
return JsonResponse({"error": "Internal server error"}, status=500)
|
||||
|
||||
organization.limit_osb_services.add(service)
|
||||
self._send_service_welcome_email(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# Generated by Django 5.2.7 on 2025-10-17 00:22
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("core", "0009_organization_limit_cloudproviders_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="organizationorigin",
|
||||
name="billing_entity",
|
||||
field=models.ForeignKey(
|
||||
help_text="If set, this billing entity will be used on new organizations with this origin.",
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
related_name="origins",
|
||||
to="core.billingentity",
|
||||
verbose_name="Billing entity",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -355,6 +355,16 @@ class OrganizationOrigin(ServalaModelMixin, models.Model):
|
|||
|
||||
name = models.CharField(max_length=100, verbose_name=_("Name"))
|
||||
description = models.TextField(blank=True, verbose_name=_("Description"))
|
||||
billing_entity = models.ForeignKey(
|
||||
to="BillingEntity",
|
||||
on_delete=models.PROTECT,
|
||||
related_name="origins",
|
||||
verbose_name=_("Billing entity"),
|
||||
help_text=_(
|
||||
"If set, this billing entity will be used on new organizations with this origin."
|
||||
),
|
||||
null=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Organization origin")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import base64
|
|||
import pytest
|
||||
|
||||
from servala.core.models import (
|
||||
BillingEntity,
|
||||
Organization,
|
||||
OrganizationMembership,
|
||||
OrganizationOrigin,
|
||||
|
|
@ -21,6 +22,11 @@ def origin():
|
|||
return OrganizationOrigin.objects.create(name="TESTORIGIN")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def billing_entity():
|
||||
return BillingEntity.objects.create(name="Test Entity")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def organization(origin):
|
||||
return Organization.objects.create(name="Test Org", origin=origin)
|
||||
|
|
|
|||
|
|
@ -99,6 +99,36 @@ def test_successful_onboarding_new_organization(
|
|||
assert "redis/offering/" in welcome_email.body
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_new_organization_inherits_origin(
|
||||
osb_client,
|
||||
test_service,
|
||||
test_service_offering,
|
||||
valid_osb_payload,
|
||||
exoscale_origin,
|
||||
instance_id,
|
||||
billing_entity,
|
||||
):
|
||||
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||
exoscale_origin.billing_entity = billing_entity
|
||||
exoscale_origin.save()
|
||||
|
||||
response = osb_client.put(
|
||||
f"/api/osb/v2/service_instances/{instance_id}",
|
||||
data=json.dumps(valid_osb_payload),
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
response_data = json.loads(response.content)
|
||||
assert response_data["message"] == "Successfully enabled service"
|
||||
|
||||
org = Organization.objects.get(osb_guid="test-org-guid-123")
|
||||
assert org.name == "Test Organization Display"
|
||||
assert org.billing_entity == exoscale_origin.billing_entity
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_duplicate_organization_returns_existing(
|
||||
osb_client,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue