def _create_offline_user_data_job(
    client,
    offline_user_data_job_service,
    customer_id,
    offline_user_data_job_type,
    external_id,
    advertiser_upload_date_time,
    bridge_map_version_id,
    partner_id,
    custom_key,
):
    """Creates an offline user data job for uploading store sales transactions.

    Args:
        client: An initialized Google Ads API client.
        offline_user_data_job_service: The offline user data job service client.
        customer_id: The Google Ads customer ID.
        offline_user_data_job_type: Optional type of offline user data in the
            job (first party or third party).
        external_id: Optional external ID for the offline user data job.
        advertiser_upload_date_time: Optional date and time the advertiser
            uploaded data to the partner. Only required for third party uploads.
        bridge_map_version_id: Optional version of partner IDs to be used for
            uploads. Only required for third party uploads.
        partner_id: Optional ID of the third party partner. Only required for
            third party uploads.
        custom_key: A custom key str to segment store sales conversions. Only
            required after creating a custom key and custom values in the
            account.

    Returns:
        The string resource name of the created job.
    """
    # TIP: If you are migrating from the AdWords API, please note that Google
    # Ads API uses the term "fraction" instead of "rate". For example,
    # loyalty_rate in the AdWords API is called loyalty_fraction in the Google
    # Ads API.

    # Create a new offline user data job.
    offline_user_data_job = client.get_type("OfflineUserDataJob")
    offline_user_data_job.type_ = offline_user_data_job_type
    if external_id is not None:
        offline_user_data_job.external_id = external_id

    # Please refer to https://support.google.com/google-ads/answer/7506124 for
    # additional details.
    store_sales_metadata = offline_user_data_job.store_sales_metadata
    # Set the fraction of your overall sales that you (or the advertiser,
    # in the third party case) can associate with a customer (email, phone
    # number, address, etc.) in your database or loyalty program.
    # For example, set this to 0.7 if you have 100 transactions over 30
    # days, and out of those 100 transactions, you can identify 70 by an
    # email address or phone number.
    store_sales_metadata.loyalty_fraction = 0.7
    # Set the fraction of sales you're uploading out of the overall sales
    # that you (or the advertiser, in the third party case) can associate
    # with a customer. In most cases, you will set this to 1.0.
    # Continuing the example above for loyalty fraction, a value of 1.0 here
    # indicates that you are uploading all 70 of the transactions that can
    # be identified by an email address or phone number.
    store_sales_metadata.transaction_upload_fraction = 1.0

    if custom_key:
        store_sales_metadata.custom_key = custom_key

    if (
        offline_user_data_job_type
        == client.enums.OfflineUserDataJobTypeEnum.STORE_SALES_UPLOAD_THIRD_PARTY
    ):
        # Create additional metadata required for uploading third party data.
        store_sales_third_party_metadata = (
            store_sales_metadata.third_party_metadata
        )
        # The date/time must be in the format "yyyy-MM-dd hh:mm:ss".
        store_sales_third_party_metadata.advertiser_upload_date_time = (
            advertiser_upload_date_time
        )
        # Set the fraction of transactions you received from the advertiser
        # that have valid formatting and values. This captures any transactions
        # the advertiser provided to you but which you are unable to upload to
        # Google due to formatting errors or missing data.
        # In most cases, you will set this to 1.0.
        store_sales_third_party_metadata.valid_transaction_fraction = 1.0
        # Set the fraction of valid transactions (as defined above) you
        # received from the advertiser that you (the third party) have matched
        # to an external user ID on your side.
        # In most cases, you will set this to 1.0.
        store_sales_third_party_metadata.partner_match_fraction = 1.0
        # Set the fraction of transactions you (the third party) are uploading
        # out of the transactions you received from the advertiser that meet
        # both of the following criteria:
        # 1. Are valid in terms of formatting and values. See valid transaction
        # fraction above.
        # 2. You matched to an external user ID on your side. See partner match
        # fraction above.
        # In most cases, you will set this to 1.0.
        store_sales_third_party_metadata.partner_upload_fraction = 1.0
        # Set the version of partner IDs to be used for uploads.
        # Please speak with your Google representative to get the values to use
        # for the bridge map version and partner IDs.
        store_sales_third_party_metadata.bridge_map_version_id = (
            bridge_map_version_id
        )
        # Set the third party partner ID uploading the transactions.
        store_sales_third_party_metadata.partner_id = partner_id

    create_offline_user_data_job_response = offline_user_data_job_service.create_offline_user_data_job(
        customer_id=customer_id, job=offline_user_data_job
    )
    offline_user_data_job_resource_name = (
        create_offline_user_data_job_response.resource_name
    )
    print(
        "Created an offline user data job with resource name "
        f"'{offline_user_data_job_resource_name}'."
    )
    return offline_user_data_job_resource_name