示例#1
0
def update_subscription_choices(subscription_id):
    """Subscriber can update their subscription choices"""
    # Get plan from subscription
    subscription = Subscription.query.get(subscription_id)
    plan = subscription.plan
    if request.method == "POST":
        chosen_option_ids = []
        for choice_group_id in request.form.keys():
            for option_id in request.form.getlist(choice_group_id):
                chosen_option_ids.append(option_id)
        # Update chosen choices
        chosen_options = []
        for option_id in chosen_option_ids:
            option = Option.query.get(option_id)
            # Store as ChosenOption because option may change after order has processed
            # This preserves integrity of the actual chosen options
            chosen_option = ChosenOption()
            chosen_option.option_title = option.title
            chosen_option.choice_group_title = option.choice_group.title
            chosen_option.choice_group_id = (
                option.choice_group.id
            )  # Used for grouping latest choice
            chosen_options.append(chosen_option)
        subscription.chosen_options = chosen_options

        database.session.add(subscription)
        database.session.commit()
        flash("Your choices have been saved.")
        return redirect(url_for("subscriber.subscriptions"))
    else:
        return render_template("subscriber/update_choices.html", plan=plan)
示例#2
0
def new_customer():
    plan = Plan.query.filter_by(uuid=request.args["plan"]).first()
    session["plan"] = plan.uuid

    # Fetch selected options, if present
    chosen_options = []
    if session.get("chosen_option_ids", None):
        for option_id in session["chosen_option_ids"]:
            option = Option.query.get(option_id)
            if option is not None:
                # We will store as ChosenOption because option may change after the order # noqa
                # has processed. This preserves integrity of the actual chosen options
                chosen_option = ChosenOption()
                chosen_option.option_title = option.title
                chosen_option.choice_group_title = option.choice_group.title
                chosen_options.append(chosen_option)
            else:
                logging.error(
                    f"Failed to get Open from session option_id: {option_id}")

    package = request.args.get("plan", "not set")
    session["package"] = package
    plan = Plan.query.filter_by(uuid=request.args.get("plan")).first()
    form = CustomerForm()
    return render_template(
        "new_customer.html",
        form=form,
        package=package,
        plan=plan,
        chosen_options=chosen_options,
    )
示例#3
0
def create_subscription(
    email=None,
    package=None,
    chosen_option_ids=None,
    subscribie_checkout_session_id=None,
    stripe_external_id=None,
    stripe_subscription_id=None,
) -> Subscription:
    """Create subscription model
    Note: A subscription model is also created if a plan only has
    one up_front payment (no recuring subscription). This allows
    the storing of chosen options againt their plan choice.
    Chosen option ids may be passed via webhook or through session
    """
    log.info("Creating Subscription model if needed")
    subscription = None  # Initalize subscription model to None

    # Store Subscription against Person locally
    if email is None:
        email = session["email"]

    if package is None:
        package = session["package"]

    person = database.session.query(Person).filter_by(email=email).one()

    # subscribie_checkout_session_id can be passed by stripe metadata (webhook) or
    # via session (e.g. when session only with no up-front payment)
    if subscribie_checkout_session_id is None:
        subscribie_checkout_session_id = session.get(
            "subscribie_checkout_session_id", None)
    log.info(
        f"subscribie_checkout_session_id is: {subscribie_checkout_session_id}")

    # Verify Subscription not already created (e.g. stripe payment webhook)
    # another hook or mandate only payment may have already created the Subscription
    # model, if so, fetch it via its subscribie_checkout_session_id
    if subscribie_checkout_session_id is not None:
        subscription = (Subscription.query.filter_by(
            subscribie_checkout_session_id=subscribie_checkout_session_id).
                        filter(Subscription.person.has(email=email)).first())

    if subscription is None:
        log.info(
            "No existing subscription model found, creating Subscription model"
        )
        # Create new subscription model
        subscription = Subscription(
            sku_uuid=package,
            person=person,
            subscribie_checkout_session_id=subscribie_checkout_session_id,
            stripe_external_id=stripe_external_id,
            stripe_subscription_id=stripe_subscription_id,
        )
        # Add chosen options (if any)
        if chosen_option_ids is None:
            chosen_option_ids = session.get("chosen_option_ids", None)

        if chosen_option_ids:
            log.info(
                f"Applying chosen_option_ids to subscription: {chosen_option_ids}"
            )
            chosen_options = []
            for option_id in chosen_option_ids:
                log.info(f"Locating option id: {option_id}")
                option = Option.query.get(option_id)
                # Store as ChosenOption because options may change after the order
                # has processed. This preserves integrity of the actual chosen options
                chosen_option = ChosenOption()
                if option is not None:
                    chosen_option.option_title = option.title
                    chosen_option.choice_group_title = option.choice_group.title
                    chosen_option.choice_group_id = (
                        option.choice_group.id
                    )  # Used for grouping latest choice
                    chosen_options.append(chosen_option)
                else:
                    log.error(
                        f"Failed to get Open from session option_id: {option_id}"
                    )
            subscription.chosen_options = chosen_options
        else:
            log.info("No chosen_option_ids were found or applied.")

        database.session.add(subscription)
        database.session.commit()
        session["subscription_uuid"] = subscription.uuid

        # If subscription plan has cancel_at set, modify Stripe subscription
        # charge_at property
        stripe.api_key = get_stripe_secret_key()
        connect_account_id = get_stripe_connect_account_id()
        if subscription.plan.cancel_at:
            cancel_at = subscription.plan.cancel_at
            try:
                stripe.Subscription.modify(
                    sid=subscription.stripe_subscription_id,
                    stripe_account=connect_account_id,
                    cancel_at=cancel_at,
                )
                subscription.stripe_cancel_at = cancel_at
                database.session.commit()
            except Exception as e:  # noqa
                log.error("Could not set cancel_at: {e}")

    newSubscriberEmailNotification()
    return subscription