Exemple #1
0
def _add_team_id(customer, default_team_id):
    team_ids = {}
    to_put = []

    def _add_team_id_for_manager(manager_email):
        regio_manager = RegioManager.get(RegioManager.create_key(manager_email))
        if regio_manager and regio_manager.team_id:
            team_ids[manager_email] = regio_manager.team_id

    to_put.append(customer)
    if customer.manager:
        _add_team_id_for_manager(customer.manager.email())
        if customer.manager.email() in team_ids:
            customer.team_id = team_ids[customer.manager.email()]
        else:
            customer.team_id = default_team_id

        for order in Order.all().ancestor(customer):
            to_put.append(order)
            if order.manager:
                if order.manager.email() not in team_ids:
                    _add_team_id_for_manager(order.manager.email())

                if order.manager.email() in team_ids:
                    order.team_id = team_ids[order.manager.email()]
                else:
                    order.team_id = default_team_id
            else:
                order.team_id = default_team_id

        for charge in Charge.all().ancestor(customer):
            to_put.append(charge)
            if charge.manager:
                if charge.manager.email() not in team_ids:
                    _add_team_id_for_manager(charge.manager.email())

                if charge.manager.email() in team_ids:
                    charge.team_id = team_ids[charge.manager.email()]
                else:
                    charge.team_id = default_team_id
            else:
                charge.team_id = default_team_id

    else:
        customer.team_id = default_team_id
        for order in Order.all().ancestor(customer):
            to_put.append(order)
            order.team_id = default_team_id
        for charge in Charge.all().ancestor(customer):
            to_put.append(charge)
            charge.team_id = default_team_id

    if to_put:
        db.put(to_put)
def _change_orders_manager(manager_email, replacement_manager_email):
    logging.info('Setting regional manager on orders from %s to %s',
                 manager_email, replacement_manager_email)
    to_put = []
    replacement_user = users.User(replacement_manager_email)
    orders = Order.all().filter('manager',
                                users.User(manager_email)).fetch(None)
    for order in orders:
        order.manager = replacement_user
        to_put.append(order)
    put_in_chunks(to_put)
Exemple #3
0
def _all_subscription_orders():
    return Order.all(keys_only=True) \
        .filter('is_subscription_order =', True) \
        .filter('next_charge_date =', NEVER_CHARGE_DATE)
Exemple #4
0
def _qry(status):
    return Order.all(keys_only=True).filter("status",
                                            Order.STATUS_SIGNED).filter(
                                                'is_subscription_order', True)
def _qry2():
    return Order.all(keys_only=True).filter('next_charge_date', None)
Exemple #6
0
    def trans():
        customer_id = order_key.parent().id()
        order, customer = db.get([order_key, Customer.create_key(customer_id)])
        if not order.next_charge_date:
            logging.warning(
                'Not creating recurrent charge for order %s (%s: %s) because no next charge date is set',
                order.order_number, customer_id, customer.name)
            return None
        elif order.next_charge_date > today:
            # Scenario: this job fails today, tomorrow this job runs again and fails again
            # -> 2 jobs for the same order would create 2 charges when the bug is fixed
            logging.warning(
                'This order has already been charged this month, skipping... %s (%s: %s)',
                order.order_number, customer_id, customer.name)
            return None
        elif customer.subscription_cancel_pending_date:
            logging.info('Disabling service from customer %s (%d)',
                         customer.name, customer.id)
            try:
                cancel_order(customer, order.order_number)
            except OrderAlreadyCanceledException as exception:
                logging.info('Order %s already canceled, continuing...',
                             exception.order.order_number)

            set_service_disabled(customer, Customer.DISABLED_OTHER)
            cleanup_expired_subscription(customer)
            return None

        logging.info("Creating recurrent charge for order %s (%s: %s)",
                     order.order_number, customer_id, customer.name)
        subscription_extension_orders = list(
            Order.all().ancestor(customer).filter(
                "next_charge_date <",
                today).filter("is_subscription_order =", False).filter(
                    'is_subscription_extension_order =',
                    True).filter("status =",
                                 Order.STATUS_SIGNED))  # type: list[Order]
        subscription_extension_order_keys = [
            o.key() for o in subscription_extension_orders
        ]
        order_item_qry = OrderItem.all().ancestor(
            customer if subscription_extension_order_keys else order)

        subscription_extension_order_item_keys = []
        total_amount = 0
        subscription_length = 0
        current_date = datetime.datetime.utcnow()
        to_put = []
        for order_item in order_item_qry:  # type: OrderItem
            product = products[order_item.product_code]
            if order_item.order_number == order.order_number:
                if product.is_subscription:
                    subscription_length = order_item.count
                if product.is_subscription or product.is_subscription_discount or product.is_subscription_extension:
                    if product.charge_interval != 1:
                        last_charge_date = datetime.datetime.utcfromtimestamp(
                            order_item.last_charge_timestamp)
                        new_charge_date = last_charge_date + relativedelta(
                            months=product.charge_interval)
                        if new_charge_date < current_date:
                            logging.debug(
                                'new_charge_date %s < current_date %s, adding %s to total_amount',
                                new_charge_date, current_date,
                                order_item.price)
                            total_amount += order_item.price
                            order_item.last_charge_timestamp = now()
                            to_put.append(order_item)
                    else:
                        total_amount += order_item.price

            elif order_item.parent().key(
            ) in subscription_extension_order_keys:
                if product.is_subscription_extension:
                    total_amount += order_item.price
                    subscription_extension_order_item_keys.append(
                        order_item.key())
        if total_amount == 0:
            order.next_charge_date = Order.default_next_charge_date()
            order.put()
            logging.info(
                "Skipping, cannot calculate recurrent charge of 0 euros for order %s (%s: %s)",
                order.order_number, customer_id, customer.name)
            return None

        if subscription_length == 0:
            raise Exception('subscription_length is 0')

        if not (customer.stripe_id and
                customer.stripe_credit_card_id) and subscription_length != 1:
            logging.debug(
                'Tried to bill customer, but no credit card info was found')
            audit_log(
                customer.id,
                'Tried to bill customer, but no credit card info was found')
            # Log the customer as expired. If this has not been done before.
            expired_subscription_key = ExpiredSubscription.create_key(
                customer_id)
            if not ExpiredSubscription.get(expired_subscription_key):
                to_put.append(
                    ExpiredSubscription(
                        key=expired_subscription_key,
                        expiration_timestamp=order.next_charge_date))
                # Create a task for the support manager
                assignee = customer.manager and customer.manager.email()
                if customer.team_id is not None:
                    team = RegioManagerTeam.get_by_id(customer.team_id)
                    if team.support_manager:
                        assignee = team.support_manager
                if assignee:
                    if customer.prospect_id:
                        prospect = Prospect.get(
                            Prospect.create_key(customer.prospect_id))
                    else:
                        # We can only create tasks for prospects. So we must create a prospect if there was none.
                        prospect = create_prospect_from_customer(customer)
                        customer.prospect_id = prospect.id
                        to_put.append(customer)
                        to_put.append(prospect)
                    to_put.append(
                        create_task(
                            created_by=None,
                            prospect_or_key=prospect,
                            assignee=assignee,
                            execution_time=today + 11 * 3600,
                            task_type=ShopTask.TYPE_SUPPORT_NEEDED,
                            app_id=prospect.app_id,
                            status=ShopTask.STATUS_NEW,
                            comment=
                            u"Customer needs to be contacted for subscription renewal",
                            notify_by_email=True))
                put_and_invalidate_cache(*to_put)
            return None
        else:
            cleanup_expired_subscription(customer)

        @db.non_transactional  # prevent contention on entity group RegioManagerTeam
        def get_currency_code():
            return customer.team.legal_entity.currency_code

        charge = Charge(parent=order_key)
        charge.date = now()
        charge.type = Charge.TYPE_RECURRING_SUBSCRIPTION
        charge.subscription_extension_length = 1
        charge.subscription_extension_order_item_keys = subscription_extension_order_item_keys
        charge.currency_code = get_currency_code()
        charge.team_id = customer.team_id
        charge.amount = total_amount
        charge.vat_pct = order.vat_pct
        charge.vat = int(total_amount * order.vat_pct / 100)
        charge.total_amount = charge.amount + charge.vat
        to_put.append(charge)

        next_charge_datetime = datetime.datetime.utcfromtimestamp(
            order.next_charge_date) + relativedelta(months=1)
        next_charge_date_int = int(
            (next_charge_datetime -
             datetime.datetime.utcfromtimestamp(0)).total_seconds())
        order.next_charge_date = next_charge_date_int
        to_put.append(order)
        for extension_order in subscription_extension_orders:
            extension_order.next_charge_date = next_charge_date_int
            to_put.append(extension_order)

        put_and_invalidate_cache(*to_put)
        return charge
Exemple #7
0
def _qry(today):
    # next_charge_date is unset for free subscriptions
    return Order.all(keys_only=True) \
        .filter("is_subscription_order =", True) \
        .filter("next_charge_date <", today) \
        .filter("status =", Order.STATUS_SIGNED)