docs: def prepare_snapshot_order_object(manager, volume, capacity, tier, upgrade):
      """Prepare the snapshot space order object for the placeOrder() method
  
      :param manager: The File or Block manager calling this function
      :param integer volume: The volume for which snapshot space is ordered
      :param integer capacity: The snapshot space size to order, in GB
      :param float tier: The tier level of the volume, in IOPS per GB (optional)
      :param boolean upgrade: Flag to indicate if this order is an upgrade
      :return: Returns the order object for the
               Product_Order service's placeOrder() method
      """
      # Ensure the storage volume has not been cancelled
      if 'billingItem' not in volume:
          raise exceptions.SoftLayerError(
              'This volume has been cancelled; unable to order snapshot space')
  
      # Determine and validate the storage volume's billing item category
      billing_item_category_code = volume['billingItem']['categoryCode']
      if billing_item_category_code == 'storage_as_a_service':
          order_type_is_saas = True
      elif billing_item_category_code == 'storage_service_enterprise':
          order_type_is_saas = False
      else:
          raise exceptions.SoftLayerError(
              "Snapshot space cannot be ordered for a primary volume with a "
              "billing item category code of '%s'" % billing_item_category_code)
  
      # Use the volume's billing item category code to get the product package
      package = get_package(manager, billing_item_category_code)
  
      # Find prices based on the volume's type and billing item category
      if order_type_is_saas:  # 'storage_as_a_service' package
          volume_storage_type = volume['storageType']['keyName']
          if 'ENDURANCE' in volume_storage_type:
              if tier is None:
                  tier = find_endurance_tier_iops_per_gb(volume)
              prices = [find_saas_snapshot_space_price(
                  package, capacity, tier=tier)]
          elif 'PERFORMANCE' in volume_storage_type:
              if not _staas_version_is_v2_or_above(volume):
                  raise exceptions.SoftLayerError(
                      "Snapshot space cannot be ordered for this performance "
                      "volume since it does not support Encryption at Rest.")
              iops = int(volume['provisionedIops'])
              prices = [find_saas_snapshot_space_price(
                  package, capacity, iops=iops)]
          else:
              raise exceptions.SoftLayerError(
                  "Storage volume does not have a valid storage type "
                  "(with an appropriate keyName to indicate the "
                  "volume is a PERFORMANCE or an ENDURANCE volume)")
      else:  # 'storage_service_enterprise' package
          if tier is None:
              tier = find_endurance_tier_iops_per_gb(volume)
          prices = [find_ent_space_price(package, 'snapshot', capacity, tier)]
  
      # Currently, these types are valid for snapshot space orders, whether
      # the base volume's order container was Enterprise or AsAService
      if upgrade:
          complex_type = 'SoftLayer_Container_Product_Order_'\
                         'Network_Storage_Enterprise_SnapshotSpace_Upgrade'
      else:
          complex_type = 'SoftLayer_Container_Product_Order_'\
                         'Network_Storage_Enterprise_SnapshotSpace'
  
      # Determine if hourly billing should be used
      hourly_billing_flag = utils.lookup(volume, 'billingItem', 'hourlyFlag')
      if hourly_billing_flag is None:
          hourly_billing_flag = False
  
      # Build and return the order object
      snapshot_space_order = {
          'complexType': complex_type,
          'packageId': package['id'],
          'prices': prices,
          'quantity': 1,
          'location': volume['billingItem']['location']['id'],
          'volumeId': volume['id'],
          'useHourlyPricing': hourly_billing_flag
      }
  
      return snapshot_space_order