docs: def prepare_duplicate_order_object(manager, origin_volume, iops, tier,
                                     duplicate_size, duplicate_snapshot_size,
                                     volume_type, hourly_billing_flag=False):
      """Prepare the duplicate order to submit to SoftLayer_Product::placeOrder()
  
      :param manager: The File or Block manager calling this function
      :param origin_volume: The origin volume which is being duplicated
      :param iops: The IOPS for the duplicate volume (performance)
      :param tier: The tier level for the duplicate volume (endurance)
      :param duplicate_size: The requested size for the duplicate volume
      :param duplicate_snapshot_size: The size for the duplicate snapshot space
      :param volume_type: The type of the origin volume ('file' or 'block')
      :param hourly_billing_flag: Billing type, monthly (False) or hourly (True)
      :return: Returns the order object to be passed to the
               placeOrder() method of the Product_Order service
      """
  
      # Verify that the origin volume has not been cancelled
      if 'billingItem' not in origin_volume:
          raise exceptions.SoftLayerError(
              "The origin volume has been cancelled; "
              "unable to order duplicate volume")
  
      # Verify that the origin volume has snapshot space (needed for duplication)
      if isinstance(utils.lookup(origin_volume, 'snapshotCapacityGb'), str):
          origin_snapshot_size = int(origin_volume['snapshotCapacityGb'])
      else:
          raise exceptions.SoftLayerError(
              "Snapshot space not found for the origin volume. "
              "Origin snapshot space is needed for duplication.")
  
      # Obtain the datacenter location ID for the duplicate
      if isinstance(utils.lookup(origin_volume, 'billingItem',
                                 'location', 'id'), int):
          location_id = origin_volume['billingItem']['location']['id']
      else:
          raise exceptions.SoftLayerError(
              "Cannot find origin volume's location")
  
      # Ensure the origin volume is STaaS v2 or higher
      # and supports Encryption at Rest
      if not _staas_version_is_v2_or_above(origin_volume):
          raise exceptions.SoftLayerError(
              "This volume cannot be duplicated since it "
              "does not support Encryption at Rest.")
  
      # If no specific snapshot space was requested for the duplicate,
      # use the origin snapshot space size
      if duplicate_snapshot_size is None:
          duplicate_snapshot_size = origin_snapshot_size
  
      # Use the origin volume size if no size was specified for the duplicate
      if duplicate_size is None:
          duplicate_size = origin_volume['capacityGb']
  
      # Get the appropriate package for the order
      # ('storage_as_a_service' is currently used for duplicate volumes)
      package = get_package(manager, 'storage_as_a_service')
  
      # Determine the IOPS or tier level for the duplicate volume, along with
      # the type and prices for the order
      origin_storage_type = origin_volume['storageType']['keyName']
      if 'PERFORMANCE' in origin_storage_type:
          volume_is_performance = True
          if iops is None:
              iops = int(origin_volume.get('provisionedIops', 0))
              if iops <= 0:
                  raise exceptions.SoftLayerError("Cannot find origin volume's provisioned IOPS")
          # Set up the price array for the order
          prices = [
              find_price_by_category(package, 'storage_as_a_service'),
              find_price_by_category(package, 'storage_' + volume_type),
              find_saas_perform_space_price(package, duplicate_size),
              find_saas_perform_iops_price(package, duplicate_size, iops),
          ]
          # Add the price code for snapshot space as well, unless 0 GB was given
          if duplicate_snapshot_size > 0:
              prices.append(find_saas_snapshot_space_price(
                  package, duplicate_snapshot_size, iops=iops))
  
      elif 'ENDURANCE' in origin_storage_type:
          volume_is_performance = False
          if tier is None:
              tier = find_endurance_tier_iops_per_gb(origin_volume)
          # Set up the price array for the order
          prices = [
              find_price_by_category(package, 'storage_as_a_service'),
              find_price_by_category(package, 'storage_' + volume_type),
              find_saas_endurance_space_price(package, duplicate_size, tier),
              find_saas_endurance_tier_price(package, tier),
          ]
          # Add the price code for snapshot space as well, unless 0 GB was given
          if duplicate_snapshot_size > 0:
              prices.append(find_saas_snapshot_space_price(
                  package, duplicate_snapshot_size, tier=tier))
  
      else:
          raise exceptions.SoftLayerError(
              "Origin volume does not have a valid storage type "
              "(with an appropriate keyName to indicate the "
              "volume is a PERFORMANCE or an ENDURANCE volume)")
  
      duplicate_order = {
          'complexType': 'SoftLayer_Container_Product_Order_'
                         'Network_Storage_AsAService',
          'packageId': package['id'],
          'prices': prices,
          'volumeSize': duplicate_size,
          'quantity': 1,
          'location': location_id,
          'duplicateOriginVolumeId': origin_volume['id'],
          'useHourlyPricing': hourly_billing_flag
      }
  
      if volume_is_performance:
          duplicate_order['iops'] = iops
  
      return duplicate_order