Exemple #1
0
def create_task_if_not_order(customer_id):
    customer = Customer.get_by_id(customer_id)
    # Check if the customer has linked his credit card after he clicked the 'pay' button
    # If he didn't (one hour after the last time he tried to pay), create a new ShopTask to call this customer.
    if not customer.stripe_valid and customer.team_id:
        if customer.prospect_id:
            rmt, prospect = db.get([
                RegioManagerTeam.create_key(customer.team_id),
                Prospect.create_key(customer.prospect_id)
            ])
        else:
            prospect = create_prospect_from_customer(customer)
            rmt = RegioManagerTeam.get(
                RegioManagerTeam.create_key(customer.team_id))
        azzert(rmt.support_manager,
               'No support manager found for team %s' % rmt.name)
        task = create_task(
            prospect_or_key=prospect,
            status=ShopTask.STATUS_NEW,
            task_type=ShopTask.TYPE_SUPPORT_NEEDED,
            address=None,
            created_by=STORE_MANAGER.email(),
            assignee=rmt.support_manager,
            execution_time=today() + 86400 + 11 * 3600,  # tomorrow, 11:00,
            app_id=prospect.app_id,
            comment=u"Customer wanted to pay an order in the customer store, "
            "but didn't succeed because he did not link his creditcard.",
            notify_by_email=True)
        task.put()
Exemple #2
0
 def trans():
     prospect = Prospect(key_name=place_id,
                         name=name,
                         app_id=app.app_id,
                         type=[],
                         categories=[u'unclassified'],
                         address=address,
                         geo_point=db.GeoPt(lat, lon),
                         assignee=assignee,
                         status=Prospect.STATUS_ADDED_BY_DISCOVERY,
                         phone=''
                         )
     task = create_task(assignee, Prospect.create_key(place_id), assignee, now() + 86400, ShopTask.TYPE_CALL,
                        app.app_id, ShopTask.STATUS_NEW, address, u'Created prospect via discovery', None, None)
     db.put([prospect, task])
     return prospect
Exemple #3
0
def create_task_for_order(customer_team_id, prospect_id, order_number):
    team, prospect = db.get([
        RegioManagerTeam.create_key(customer_team_id),
        Prospect.create_key(prospect_id)
    ])
    azzert(team.support_manager,
           u'No support manager found for team %s' % team.name)
    comment = u'Customer placed a new order: %s' % (order_number)
    task = create_task(
        created_by=STORE_MANAGER.email(),
        prospect_or_key=prospect,
        app_id=prospect.app_id,
        status=ShopTask.STATUS_NEW,
        task_type=ShopTask.TYPE_SUPPORT_NEEDED,
        address=None,
        assignee=team.support_manager,
        comment=comment,
        execution_time=today() + 86400 + 11 * 3600,  # tomorrow at 11:00
        notify_by_email=True)
    task.put()
    broadcast_task_updates([team.support_manager])
    def trans():
        charge = None
        expired_subscription, customer = db.get([ExpiredSubscription.create_key(customer_id),
                                                       Customer.create_key(customer_id)])
        expired_subscription.status = status
        expired_subscription.status_updated_timestamp = now()

        if status == ExpiredSubscription.STATUS_WILL_LINK_CREDIT_CARD:
            # Create a task for regiomanager to check if the customer has linked his credit card after two weeks.
            # the ExpiredSubscription object from this customer will be cleaned up in recurrentbilling the day after he has linked it.
            to_put.append(expired_subscription)
            team, prospect = db.get([RegioManagerTeam.create_key(customer.team_id),
                                     Prospect.create_key(customer.prospect_id)])
            execution_time = now() + DAY * 14
            date_string = datetime.datetime.utcfromtimestamp(execution_time).strftime(u'%A %d %b %Y')
            comment = u'Check if the customer has linked his creditcard (for automatic subscription renewal).' \
                      u' If he hasn\'t linked it before %s, contact him again.' % date_string
            task = create_task(current_user.email(), prospect, team.support_manager, execution_time,
                               ShopTask.TYPE_CHECK_CREDIT_CARD, prospect.app_id, comment=comment)
            to_put.append(task)

        elif status == ExpiredSubscription.STATUS_EXTEND_SUBSCRIPTION:
            # Creates a new charge using the customer his subscription order.
            subscription_order, team = db.get([Order.create_key(customer.id, customer.subscription_order_number),
                                               RegioManagerTeam.create_key(customer.team_id)])
            extension_order_item_keys = list()
            order_items = list(OrderItem.list_by_order(subscription_order.key()))
            products_to_get = list()
            for item in order_items:
                products_to_get.append(Product.create_key(item.product_code))
            products = {p.code: p for p in Product.get(products_to_get)}
            # extend per year
            months = 12
            total_amount = 0
            for item in order_items:
                product = products[item.product_code]
                if product.is_subscription and item.price > 0:
                    total_amount += months * item.price
                elif not product.is_subscription and (product.is_subscription_discount or product.extra_subscription_months > 0):
                    total_amount += months * item.price
                elif product.is_subscription_extension:
                    total_amount += months * item.price
                    extension_order_item_keys.append(item.key())

            if total_amount <= 0:
                raise BusinessException('The created charge has a negative amount (%d)' % total_amount)
            next_charge_datetime = datetime.datetime.utcfromtimestamp(now()) + relativedelta(months=months)
            subscription_order.next_charge_date = get_epoch_from_datetime(next_charge_datetime)
            to_put.append(subscription_order)

            # reconnect all previously connected friends if the service was disabled in the past
            if customer.service_disabled_at != 0:
                deferred.defer(set_service_enabled, customer.id, _transactional=True)

            vat_pct = get_vat_pct(customer, team)
            charge = Charge(parent=subscription_order)
            charge.date = now()
            charge.type = Charge.TYPE_SUBSCRIPTION_EXTENSION
            charge.subscription_extension_length = months
            charge.subscription_extension_order_item_keys = extension_order_item_keys
            charge.amount = total_amount
            charge.vat_pct = vat_pct
            charge.vat = int(total_amount * vat_pct / 100)
            charge.total_amount = charge.amount + charge.vat
            charge.currency_code = team.legal_entity.currency_code
            to_put.append(charge)
            to_delete.append(expired_subscription)

        db.put(to_put)
        if to_delete:
            db.delete(to_delete)

        return charge
Exemple #5
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