Skip to content

Outlet Management

Complete guide to managing outlets, business hours, settings, and analytics in the Reserva platform.


Overview

The outlet management system provides comprehensive tools for:

  • Outlet CRUD Operations - Create, read, update, and delete outlet locations
  • Business Hours Management - Configure operating hours for each day of the week
  • Advanced Search - Filter and search outlets by status, name, or location
  • Subscription Limit Enforcement - Automatic validation against plan limits
  • Outlet Statistics - Performance metrics and analytics per location
  • Multi-Tenant Isolation - Strict tenant-based data separation
  • Soft Delete Support - Preserve data for audit trail purposes

Key Concepts:

  • Outlet = Physical business location under a tenant (brand)
  • Tenant = Brand/business that owns multiple outlets
  • Slug = Unique URL-friendly identifier per outlet within tenant
  • Business Hours = Weekly operating schedule with open/close times
  • Soft Delete = Outlet marked deleted, data preserved for audit
  • Subscription Limit = Maximum outlets allowed by subscription plan

Subscription Plan Limits

Outlet creation is strictly limited by subscription plan.

Plan Limits

Plan Max Outlets Notes
FREE 1 Single location only
PRO 10 Supports multi-location businesses
ENTERPRISE Unlimited (-1) No outlet limit

Enforcement:

  • Outlet creation fails with HTTP 402 Payment Required if limit exceeded
  • Current outlet count checked before creation
  • Deleted outlets (soft delete) still count toward limit
  • Upgrade subscription to increase outlet limit

Error Response When Limit Exceeded:

{
  "detail": "Subscription limit reached. Maximum outlets allowed: 1"
}

See Subscription Management - Available Plans for complete plan details and Subscription Upgrade to increase limits.


List Tenant Outlets

Retrieve paginated list of outlets with advanced filtering and sorting.

Endpoint

GET /api/v1/outlets

Authentication: Required (JWT token) Access: All staff members

Query Parameters

Parameter Type Required Description Example
page integer No Page number (starts from 1) 1
size integer No Items per page (max 100, default 20) 20
status string No Filter by outlet status "active"
search string No Search by name or location "Downtown"
sort_by string No Field to sort by "name"
sort_order string No Sort order: asc or desc "asc"

Outlet Statuses

  • active - Outlet is operational and accepting bookings
  • inactive - Outlet temporarily closed or not accepting bookings
  • maintenance - Outlet under maintenance or renovation
  • permanently_closed - Outlet permanently closed (typically soft-deleted)

Response

{
  "items": [
    {
      "id": "507f1f77bcf86cd799439011",
      "tenant_id": "507f1f77bcf86cd799439010",
      "name": "Downtown Beauty Spa",
      "slug": "downtown-spa",
      "description": "Our flagship downtown location",
      "status": "active",
      "address": {
        "street": "123 Main Street",
        "city": "New York",
        "state": "NY",
        "postal_code": "10001",
        "country": "US",
        "district": "Manhattan"
      },
      "contact": {
        "phone": "+1234567890",
        "email": "downtown@beautyspa.com",
        "website": "https://beautyspa.com"
      },
      "business_hours": [
        {
          "day": 0,
          "is_open": true,
          "open_time": "09:00",
          "close_time": "18:00"
        },
        {
          "day": 1,
          "is_open": true,
          "open_time": "09:00",
          "close_time": "18:00"
        },
        {
          "day": 2,
          "is_open": true,
          "open_time": "09:00",
          "close_time": "18:00"
        },
        {
          "day": 3,
          "is_open": true,
          "open_time": "09:00",
          "close_time": "18:00"
        },
        {
          "day": 4,
          "is_open": true,
          "open_time": "09:00",
          "close_time": "18:00"
        },
        {
          "day": 5,
          "is_open": true,
          "open_time": "10:00",
          "close_time": "16:00"
        },
        {
          "day": 6,
          "is_open": false,
          "open_time": null,
          "close_time": null
        }
      ],
      "settings": {
        "accepts_online_booking": true,
        "requires_appointment": true,
        "walk_ins_allowed": true,
        "advance_booking_days": 30,
        "cancellation_hours": 24,
        "auto_confirm_bookings": false,
        "payment_required_upfront": false,
        "timezone": "America/New_York",
        "default_service_buffer_minutes": 15,
        "accepts_online_payment": true,
        "accepts_cash_payment": true,
        "payment_on_arrival": false
      },
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2025-01-20T14:45:00Z"
    }
  ],
  "total": 5,
  "page": 1,
  "size": 20,
  "pages": 1
}

Search Behavior

Full-text search across:

  • Outlet name
  • City name
  • District/region name

Case-insensitive matching with regex support.

Business Hours Format

Day of Week Numbering:

  • 0 = Monday
  • 1 = Tuesday
  • 2 = Wednesday
  • 3 = Thursday
  • 4 = Friday
  • 5 = Saturday
  • 6 = Sunday

Time Format: 24-hour format (HH:MM), e.g., "09:00", "18:00"

Closed Days: Set is_open: false, open_time and close_time will be null


Create New Outlet

Create a new outlet with automatic validation and subscription limit checking.

Endpoint

POST /api/v1/outlets

Authentication: Required (JWT token) Access: TENANT_ADMIN, OUTLET_MANAGER, or SUPER_ADMIN

Request Body

{
  "name": "Downtown Beauty Spa",
  "slug": "downtown-spa",
  "description": "Our flagship downtown location",
  "status": "active",
  "address": {
    "street": "123 Main Street",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US",
    "district": "Manhattan"
  },
  "contact": {
    "phone": "+1234567890",
    "email": "downtown@beautyspa.com",
    "website": "https://beautyspa.com"
  },
  "business_hours": [
    {
      "day": 0,
      "is_open": true,
      "open_time": "09:00",
      "close_time": "18:00"
    },
    {
      "day": 1,
      "is_open": true,
      "open_time": "09:00",
      "close_time": "18:00"
    },
    {
      "day": 2,
      "is_open": true,
      "open_time": "09:00",
      "close_time": "18:00"
    },
    {
      "day": 3,
      "is_open": true,
      "open_time": "09:00",
      "close_time": "18:00"
    },
    {
      "day": 4,
      "is_open": true,
      "open_time": "09:00",
      "close_time": "18:00"
    },
    {
      "day": 5,
      "is_open": true,
      "open_time": "10:00",
      "close_time": "16:00"
    },
    {
      "day": 6,
      "is_open": false
    }
  ],
  "settings": {
    "accepts_online_booking": true,
    "requires_appointment": true,
    "walk_ins_allowed": true,
    "advance_booking_days": 30,
    "cancellation_hours": 24,
    "auto_confirm_bookings": false,
    "payment_required_upfront": false,
    "timezone": "America/New_York",
    "default_service_buffer_minutes": 15,
    "accepts_online_payment": true,
    "accepts_cash_payment": true,
    "payment_on_arrival": false
  }
}

Request Fields

Field Type Required Description Validation
name string Yes Outlet display name 1-200 characters
slug string Yes URL-friendly identifier Lowercase, hyphens, unique per tenant
description string No Outlet description Max 1000 characters
status string No Outlet status active, inactive, maintenance (default: active)
address object Yes Physical address See Address schema below
contact object Yes Contact information See Contact schema below
business_hours array No Weekly operating hours 7 entries (Mon-Sun), see BusinessHours schema
settings object No Operational settings See Settings schema below

Address Schema

Field Type Required Description
street string Yes Street address
city string Yes City name
state string Yes State/province code
postal_code string Yes Postal/ZIP code
country string Yes Country code (ISO 3166-1 alpha-2)
district string No District/region name

Contact Schema

Field Type Required Description Validation
phone string Yes Phone number Valid phone format with country code
email string Yes Email address Valid email format
website string No Website URL Valid URL format

Settings Schema

Field Type Default Description
accepts_online_booking boolean true Allow online bookings
requires_appointment boolean true Appointment required for service
walk_ins_allowed boolean true Accept walk-in customers
advance_booking_days integer 30 Max days in advance for booking
cancellation_hours integer 24 Hours before appointment for free cancellation
auto_confirm_bookings boolean false Automatically confirm bookings
payment_required_upfront boolean false Require payment before appointment
timezone string "UTC" IANA timezone identifier
default_service_buffer_minutes integer 15 Buffer time between services
accepts_online_payment boolean true Accept online payment methods
accepts_cash_payment boolean true Accept cash payments
payment_on_arrival boolean false Payment at outlet on arrival

Response

Returns complete outlet profile with generated ID (same format as List Outlets items).

Status Code: 201 Created

Business Rules

  1. Subscription Limit Enforcement:

  2. Current outlet count checked against subscription plan limit

  3. Returns 402 Payment Required if limit exceeded
  4. Deleted outlets count toward limit

  5. Slug Uniqueness:

  6. Slug must be unique within the tenant

  7. Returns 409 Conflict if duplicate slug exists
  8. Case-insensitive uniqueness check

  9. Business Hours Validation:

  10. Time format must be HH:MM (24-hour)

  11. Open time must be before close time
  12. All 7 days must be defined (Monday=0 to Sunday=6)
  13. Closed days: set is_open: false

  14. Default Status:

  15. If not provided, status defaults to active

  16. Newly created outlets are immediately operational

Error Responses

402 Payment Required - Subscription Limit:

{
  "detail": "Subscription limit reached. Maximum outlets allowed: 1"
}

409 Conflict - Duplicate Slug:

{
  "detail": "Outlet with slug 'downtown-spa' already exists for this tenant"
}

400 Bad Request - Invalid Business Hours:

{
  "detail": "Invalid business hours: open_time must be before close_time"
}

400 Bad Request - Validation Error:

{
  "detail": [
    {
      "loc": ["body", "contact", "email"],
      "msg": "value is not a valid email address",
      "type": "value_error.email"
    }
  ]
}

Process Flow

  1. Subscription Limit Check - Validate outlet count against plan limit
  2. Slug Uniqueness Check - Ensure slug is unique within tenant
  3. Business Hours Validation - Validate time format and logic
  4. Outlet Creation - Create outlet record with tenant isolation
  5. Default Settings Initialization - Apply default operational settings
  6. Return Profile - Return complete outlet profile with ID

Get Outlet Details

Retrieve comprehensive outlet information by ID.

Endpoint

GET /api/v1/outlets/{outlet_id}

Authentication: Required (JWT token) Access: All staff members

Path Parameters

Parameter Type Required Description
outlet_id string Yes Outlet ID (MongoDB ObjectId)

Response

Returns complete outlet profile (same format as List Outlets items).

Error Responses

400 Bad Request - Invalid ID:

{
  "detail": "Invalid outlet ID format"
}

404 Not Found:

{
  "detail": "Outlet not found"
}

Note: Returns 404 if outlet doesn't exist or belongs to different tenant (tenant isolation).


Update Outlet Information

Update outlet information with validation and conflict checking.

Endpoint

PUT /api/v1/outlets/{outlet_id}

Authentication: Required (JWT token) Access: TENANT_ADMIN, OUTLET_MANAGER, or SUPER_ADMIN

Path Parameters

Parameter Type Required Description
outlet_id string Yes Outlet ID (MongoDB ObjectId)

Request Body

All fields are optional. Only provided fields will be updated.

{
  "name": "Updated Spa Name",
  "description": "Updated description for the spa",
  "status": "inactive",
  "business_hours": [
    {
      "day": 0,
      "is_open": true,
      "open_time": "10:00",
      "close_time": "20:00"
    }
  ],
  "settings": {
    "advance_booking_days": 45,
    "cancellation_hours": 48,
    "timezone": "America/Los_Angeles"
  }
}

Response

Returns updated outlet profile with all current information (same format as Get Outlet Details).

Business Rules

  1. Partial Updates:
  2. Only fields provided in request body are updated
  3. Unchanged fields remain as-is
  4. Nested objects (settings, contact) can be partially updated

  5. Slug Uniqueness:

  6. If slug is changed, uniqueness is re-validated
  7. Returns 409 Conflict if new slug already exists

  8. Business Hours Validation:

  9. If business_hours provided, full validation applies
  10. Time format and logic validated
  11. Can update individual days or entire week

  12. Protected Fields:

  13. tenant_id cannot be changed
  14. created_at cannot be changed
  15. id cannot be changed

Error Responses

409 Conflict - Duplicate Slug:

{
  "detail": "Outlet with slug 'new-slug' already exists for this tenant"
}

400 Bad Request - Invalid Business Hours:

{
  "detail": "Invalid business hours: open_time must be before close_time"
}


Delete Outlet

Soft delete an outlet with dependency validation.

Endpoint

DELETE /api/v1/outlets/{outlet_id}

Authentication: Required (JWT token) Access: TENANT_ADMIN or SUPER_ADMIN

Path Parameters

Parameter Type Required Description
outlet_id string Yes Outlet ID (MongoDB ObjectId)

Response

{
  "message": "Outlet has been deleted successfully"
}

Status Code: 200 OK

Delete Behavior

Soft Delete (Default):

  • Sets is_deleted: true flag
  • Changes status to permanently_closed
  • Preserves all outlet data
  • Excluded from normal queries
  • Maintains referential integrity
  • Can be restored by admin

Note: This endpoint performs soft delete only. Hard delete is not supported to maintain data integrity and audit trail.

Business Rules

  1. Active Appointments Check:

  2. Cannot delete outlet with active appointments

  3. Returns 409 Conflict if appointments exist
  4. Must cancel/complete all appointments first

  5. Data Preservation:

  6. All outlet data preserved in database

  7. Appointment history remains intact
  8. Staff assignments preserved

  9. Subscription Impact:

  10. Deleted outlets still count toward subscription limit

  11. To free up outlet slots, contact support for hard delete

Error Responses

409 Conflict - Active Appointments:

{
  "detail": "Cannot delete outlet with active appointments"
}

404 Not Found:

{
  "detail": "Outlet not found"
}


Get Outlet Statistics

Retrieve comprehensive performance statistics and analytics for an outlet.

Endpoint

GET /api/v1/outlets/{outlet_id}/stats

Authentication: Required (JWT token) Access: All staff members

Path Parameters

Parameter Type Required Description
outlet_id string Yes Outlet ID (MongoDB ObjectId)

Query Parameters

Parameter Type Required Description Example
period string No Time period for statistics "month"

Period Options: - week - Last 7 days - month - Last 30 days (default) - quarter - Last 90 days - year - Last 365 days

Response

{
  "outlet_id": "507f1f77bcf86cd799439011",
  "outlet_name": "Downtown Beauty Spa",
  "period": "month",
  "overview": {
    "total_appointments": 245,
    "completed_appointments": 220,
    "cancelled_appointments": 15,
    "no_show_appointments": 10
  },
  "revenue": {
    "total_revenue": 12500000.00,
    "average_transaction": 51020.41,
    "top_services": [
      {
        "service_id": "507f1f77bcf86cd799439020",
        "service_name": "Hair Coloring",
        "bookings": 85,
        "revenue": 4250000.00
      },
      {
        "service_id": "507f1f77bcf86cd799439021",
        "service_name": "Facial Treatment",
        "bookings": 65,
        "revenue": 2600000.00
      }
    ]
  },
  "customers": {
    "total_customers": 180,
    "new_customers": 45,
    "returning_customers": 135,
    "average_rating": 4.7
  },
  "staff": {
    "total_staff": 12,
    "utilization_rate": 78.5,
    "top_performers": [
      {
        "staff_id": "507f1f77bcf86cd799439030",
        "staff_name": "Sarah Johnson",
        "completed_appointments": 42,
        "revenue_generated": 2100000.00,
        "average_rating": 4.9
      }
    ]
  },
  "operational": {
    "average_booking_lead_time_hours": 48,
    "peak_hours": ["14:00", "15:00", "16:00"],
    "busiest_days": ["Friday", "Saturday"]
  },
  "updated_at": "2025-10-08T10:00:00Z"
}

Metric Definitions

Overview Metrics:

  • total_appointments - Total appointments in period
  • completed_appointments - Successfully completed appointments
  • cancelled_appointments - Cancelled appointments
  • no_show_appointments - Customers who didn't show up

Revenue Metrics:

  • total_revenue - Sum of all completed appointment payments
  • average_transaction - Total revenue ÷ completed appointments
  • top_services - Services ranked by revenue

Customer Metrics:

  • total_customers - Unique customers served
  • new_customers - First-time customers in period
  • returning_customers - Repeat customers
  • average_rating - Average customer satisfaction rating

Staff Metrics:

  • total_staff - Number of active staff at outlet
  • utilization_rate - % of available time with bookings
  • top_performers - Staff ranked by completed appointments

Operational Metrics:

  • average_booking_lead_time_hours - Hours between booking and appointment
  • peak_hours - Hours with most appointments
  • busiest_days - Days of week with most appointments

Performance Notes

Data Sources:

  • Aggregated from appointments, payments, and reviews collections
  • Statistics cached and updated periodically
  • Real-time updates for critical metrics
  • May take several seconds for large datasets

Access Control

  • All staff members can view outlet statistics
  • Statistics scoped to current tenant only
  • Cannot view statistics for outlets in other tenants

Get Business Hours

Retrieve complete business hours configuration for an outlet.

Endpoint

GET /api/v1/outlets/{outlet_id}/business-hours

Authentication: Required (JWT token) Access: All staff members

Path Parameters

Parameter Type Required Description
outlet_id string Yes Outlet ID (MongoDB ObjectId)

Response

[
  {
    "day": 0,
    "is_open": true,
    "open_time": "09:00",
    "close_time": "18:00"
  },
  {
    "day": 1,
    "is_open": true,
    "open_time": "09:00",
    "close_time": "18:00"
  },
  {
    "day": 2,
    "is_open": true,
    "open_time": "09:00",
    "close_time": "18:00"
  },
  {
    "day": 3,
    "is_open": true,
    "open_time": "09:00",
    "close_time": "18:00"
  },
  {
    "day": 4,
    "is_open": true,
    "open_time": "09:00",
    "close_time": "18:00"
  },
  {
    "day": 5,
    "is_open": true,
    "open_time": "10:00",
    "close_time": "16:00"
  },
  {
    "day": 6,
    "is_open": false,
    "open_time": null,
    "close_time": null
  }
]

Business Hours Schema

Field Type Description
day integer Day of week (0=Monday, 6=Sunday)
is_open boolean Whether outlet is open on this day
open_time string Opening time in HH:MM format (24-hour)
close_time string Closing time in HH:MM format (24-hour)

Note: For closed days (is_open: false), open_time and close_time will be null.

Default Hours

If outlet has no custom business hours configured, returns default hours:

  • Monday-Saturday: 09:00 - 18:00
  • Sunday: Closed

Use Cases

Booking Availability:

  • Check if outlet is open on specific day
  • Validate appointment time within business hours
  • Calculate available time slots

Display Hours:

  • Show business hours on customer-facing pages
  • Generate "Open Now" / "Closed" indicators
  • Display next opening time

Best Practices

For Outlet Creation

DO:

  • Check current subscription limit before creating
  • Use descriptive, unique slugs (e.g., "downtown-manhattan")
  • Define business hours for all 7 days
  • Set realistic advance booking days
  • Configure timezone correctly for the outlet location
  • Enable appropriate payment methods

DON'T:

  • Create outlets without checking subscription limits
  • Use generic slugs (e.g., "outlet1", "location")
  • Skip business hours configuration
  • Use UTC timezone for all outlets (use local timezone)
  • Enable all payment methods without verification

For Outlet Updates

DO:

  • Update business hours when schedule changes
  • Adjust cancellation hours based on business needs
  • Keep contact information current
  • Use maintenance status during renovations
  • Validate slug uniqueness when changing

DON'T:

  • Change slug frequently (breaks URLs)
  • Update timezone without considering existing appointments
  • Reduce advance_booking_days below existing bookings
  • Change tenant_id (violates tenant isolation)

For Outlet Deletion

DO:

  • Cancel all active appointments first
  • Notify customers of closure
  • Update staff assignments
  • Archive important data before deletion
  • Use soft delete for data preservation

DON'T:

  • Delete outlets with pending appointments
  • Skip customer notifications
  • Hard delete without business approval
  • Delete primary/flagship outlet without replacement

For Multi-Outlet Management

DO:

  • Use consistent naming conventions
  • Standardize business hours across similar outlets
  • Configure settings appropriately per location
  • Monitor outlet statistics regularly
  • Plan for subscription limit increases

DON'T:

  • Create too many outlets on FREE plan (max 1)
  • Use identical slugs for different outlets
  • Ignore local regulations per outlet location
  • Set different cancellation policies without reason

Integration Examples

Create Outlet (Downtown Location)

curl -X POST https://api.example.com/api/v1/outlets \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Downtown Beauty Spa",
    "slug": "downtown-spa",
    "description": "Our flagship downtown location",
    "status": "active",
    "address": {
      "street": "123 Main Street",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "country": "US"
    },
    "contact": {
      "phone": "+1234567890",
      "email": "downtown@beautyspa.com"
    },
    "business_hours": [
      {"day": 0, "is_open": true, "open_time": "09:00", "close_time": "18:00"},
      {"day": 1, "is_open": true, "open_time": "09:00", "close_time": "18:00"},
      {"day": 2, "is_open": true, "open_time": "09:00", "close_time": "18:00"},
      {"day": 3, "is_open": true, "open_time": "09:00", "close_time": "18:00"},
      {"day": 4, "is_open": true, "open_time": "09:00", "close_time": "18:00"},
      {"day": 5, "is_open": true, "open_time": "10:00", "close_time": "16:00"},
      {"day": 6, "is_open": false}
    ],
    "settings": {
      "accepts_online_booking": true,
      "advance_booking_days": 30,
      "cancellation_hours": 24,
      "timezone": "America/New_York"
    }
  }'

List Active Outlets

curl -X GET "https://api.example.com/api/v1/outlets?status=active&page=1&size=20" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Update Business Hours (Extended Weekend Hours)

curl -X PUT https://api.example.com/api/v1/outlets/507f1f77bcf86cd799439011 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "business_hours": [
      {"day": 5, "is_open": true, "open_time": "09:00", "close_time": "20:00"},
      {"day": 6, "is_open": true, "open_time": "10:00", "close_time": "18:00"}
    ]
  }'

Get Outlet Statistics (Last Quarter)

curl -X GET "https://api.example.com/api/v1/outlets/507f1f77bcf86cd799439011/stats?period=quarter" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Search Outlets by Location

curl -X GET "https://api.example.com/api/v1/outlets?search=Manhattan&sort_by=name&sort_order=asc" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Error Handling

Common Error Codes

Status Code Error Type Description Resolution
400 Bad Request Invalid input data Check request body format and field values
401 Not Authenticated Missing or invalid JWT token Provide valid authentication token
402 Payment Required Subscription limit exceeded Upgrade subscription plan
403 Forbidden Insufficient permissions Check user role (requires TENANT_ADMIN+)
404 Not Found Outlet not found Verify outlet ID exists
409 Conflict Duplicate slug or active appointments Use different slug or resolve dependencies

Example Error Responses

Subscription Limit Error:

{
  "detail": "Subscription limit reached. Maximum outlets allowed: 1"
}

Duplicate Slug Error:

{
  "detail": "Outlet with slug 'downtown-spa' already exists for this tenant"
}

Invalid Business Hours:

{
  "detail": "Invalid business hours: open_time must be before close_time"
}

Tenant Isolation Error:

{
  "detail": "Outlet not found"
}
Note: Returns 404 even if outlet exists but belongs to different tenant (security).


API Reference Summary

Endpoint Method Purpose Access Level
/outlets GET List all outlets with filtering All staff
/outlets POST Create new outlet TENANT_ADMIN+
/outlets/{outlet_id} GET Get outlet details All staff
/outlets/{outlet_id} PUT Update outlet TENANT_ADMIN+
/outlets/{outlet_id} DELETE Delete outlet (soft) TENANT_ADMIN+
/outlets/{outlet_id}/stats GET Get statistics All staff
/outlets/{outlet_id}/business-hours GET Get business hours All staff


Next Steps:

  1. Review current subscription plan and outlet limits
  2. Create outlets for each physical location
  3. Configure business hours and operational settings
  4. Set up payment methods and booking preferences
  5. Monitor outlet statistics and performance
  6. Upgrade subscription if more outlets needed

For subscription limit increases, refer to the Subscription Upgrade section.