Example #1
0
def get_subscription_order(customer_id):
    customer = Customer.get_by_id(customer_id)
    if not customer.subscription_order_number:
        raise NoSubscriptionException(customer)
    order = Order.get_by_order_number(customer.id,
                                      customer.subscription_order_number)
    if not order.status == Order.STATUS_SIGNED:
        raise BusinessException(
            'The customer his subscription order has not been signed yet.')
    return order
Example #2
0
def set_next_charge_date(customer_id, next_charge_date):
    customer = Customer.get_by_id(customer_id)
    if not customer.subscription_order_number:
        raise NoSubscriptionException(customer)
    order = Order.get_by_order_number(customer_id,
                                      customer.subscription_order_number)
    if not order.status == Order.STATUS_SIGNED:
        raise BusinessException(
            'The customer his subscription order has not been signed yet.')
    order.next_charge_date = next_charge_date
    order.put()
    def test_customer_store(self):
        xcty_product = ShopProductTO.create(u'be-berlare', u'XCTY', 1)
        posm_product = ShopProductTO.create(MISSING, u'POSM', 250)
        _, customer = self._create_customer_and_subscription_order(
            [u'MSUP', u'BEAC', u'KSUP', u'ILOS'])
        self._create_service(customer)
        customer = Customer.get_by_id(customer.id)
        self.current_user = users.User(customer.service_email)
        set_current_user(self.current_user)
        product_xcty, product_posm = db.get(
            [Product.create_key(u'XCTY'),
             Product.create_key(u'POSM')])

        xcty_order_item = add_item_to_order(xcty_product).order_item
        remaining_subscription_length = get_subscription_order_remaining_length(
            customer.id, customer.subscription_order_number)[0]
        price_xcty = remaining_subscription_length * product_xcty.price
        temp_order = Order.get_by_order_number(customer.id, '-1')
        self.assertEqual(temp_order.is_subscription_order, False)
        self.assertEqual(temp_order.amount, price_xcty)
        self.assertEqual(temp_order.is_subscription_extension_order,
                         False)  # Is set when paying the order

        add_item_to_order(posm_product).order_item
        temp_order = Order.get_by_order_number(customer.id, '-1')
        self.assertEqual(temp_order.amount,
                         price_xcty + product_posm.price * 250)

        # test removing an order item
        remove_from_order(xcty_order_item.id)
        temp_order = Order.get_by_order_number(customer.id, '-1')
        self.assertEqual(temp_order.amount, product_posm.price * 250)

        xcty_order_item = add_item_to_order(xcty_product).order_item
        temp_order = Order.get_by_order_number(customer.id, '-1')
        self.assertEqual(temp_order.amount,
                         price_xcty + product_posm.price * 250)
        self.assertEqual(
            pay_order().success,
            False)  # should be false since we have no credit card linked
Example #4
0
def cancel_charge(customer_id, order_number, charge_id):
    """Cancels a charge so adjustments can be made to the order. Rolls back the next charge date of the subscription order.

    Args:
        customer_id:
        order_number:
        charge_id:

    Returns:
        None
    """
    to_put = list()
    now_ = now()
    charge, order, customer = db.get([Charge.create_key(charge_id, order_number, customer_id),
                                      Order.create_key(customer_id, order_number),
                                      Customer.create_key(customer_id)])
    charge.date_cancelled = now_
    charge.status = Charge.STATUS_CANCELLED
    to_put.append(charge)
    order_items = list(OrderItem.list_by_order(order.key()))
    if order.is_subscription_order:
        months = 0
        for item in order_items:
            product = item.product
            if product.is_subscription and product.price > 0:
                months += item.count
            if not product.is_subscription and product.extra_subscription_months > 0:
                months += product.extra_subscription_months

        if months > 0:
            next_charge_datetime = datetime.datetime.utcfromtimestamp(now()) - relativedelta(months=months)
            order.next_charge_date = get_epoch_from_datetime(next_charge_datetime)
        else:
            order.next_charge_date = Order.default_next_charge_date()
    else:
        extra_months = 0
        for item in order_items:
            product = item.product
            if not product.is_subscription and product.extra_subscription_months > 0:
                extra_months += product.extra_subscription_months

        if extra_months > 0:
            sub_order = Order.get_by_order_number(customer_id, customer.subscription_order_number)
            next_charge_datetime = datetime.datetime.utcfromtimestamp(sub_order.next_charge_date) - relativedelta(
                months=extra_months)
            sub_order.next_charge_date = get_epoch_from_datetime(next_charge_datetime)
            to_put.append(sub_order)
    db.put(to_put)
Example #5
0
def cancel_subscription(customer_id, cancel_reason, immediately=False):
    """
    Marks the customer his subscription as disabled.
    Recurrent billing will disable the service and disconnect all users after the subscription has ended.
    When the 'immediately' parameter is set, the service will be disabled immediately.

    Args:
        customer_id (int, long): Customer id
        cancel_reason (unicode): Reason why the subscription has been canceled.
        immediately (bool): Set to True to disable the service immediately

    Returns: None

    Raises:
        EmptyValueException
        CustomerNotFoundException
        NoSubscriptionException
    """
    if not cancel_reason:
        raise EmptyValueException('cancel_reason')

    customer = Customer.get_by_id(customer_id)

    if not customer.subscription_order_number:
        raise NoSubscriptionException(customer)

    order = Order.get_by_order_number(customer_id,
                                      customer.subscription_order_number)
    if immediately or order.status != Order.STATUS_SIGNED:

        def trans():
            try:
                cancel_order(customer, customer.subscription_order_number)
            except OrderAlreadyCanceledException as exception:
                logging.info('Order %s already canceled, continueing...' %
                             exception.order.order_number)

            customer.disabled_reason = cancel_reason
            set_service_disabled(customer, Customer.DISABLED_OTHER)

        run_in_xg_transaction(trans)
    else:
        customer.disabled_reason = cancel_reason
        customer.subscription_cancel_pending_date = now()
        customer.put()
def _job():
    products = {p.code: p for p in Product.all()}
    order_keys = set()
    for order_item in OrderItem.all():
        if products[order_item.product_code].is_subscription_extension:
            order_keys.add(order_item.order_key)

    orders = db.get(order_keys)
    to_put = list()
    for order in orders:
        if not order.is_subscription_extension_order:
            order.is_subscription_extension_order = True
            customer = order.parent()
            subscription_order = Order.get_by_order_number(customer.id, customer.subscription_order_number)
            order.next_charge_date = subscription_order.next_charge_date
            to_put.append(order)

    for chunk in chunks(to_put, 200):
        db.put(chunk)
Example #7
0
    def trans():
        old_order, team = db.get(
            (old_order_key, RegioManagerTeam.create_key(customer.team_id)))

        if not old_order:
            return BoolReturnStatusTO.create(
                False,
                translate(
                    get_solution_settings(service_user).main_language,
                    SOLUTION_COMMON, u'cart_empty'), False)

        # Duplicate the order
        to_put = list()
        to_delete = list()
        properties = copy_model_properties(old_order)
        properties['status'] = Order.STATUS_SIGNED
        properties['date_signed'] = now()
        new_order_key = Order.create_key(
            customer.id, OrderNumber.next(team.legal_entity_key))
        new_order = Order(key=new_order_key, **properties)
        new_order.team_id = team.id
        to_delete.append(old_order)

        # duplicate all of the order items
        old_order_items = OrderItem.list_by_order(old_order_key)
        all_products = db.get([
            Product.create_key(item.product_code) for item in old_order_items
        ])
        is_subscription_extension_order = False
        for product in all_products:
            if product.is_subscription_extension:
                is_subscription_extension_order = True
                break
        new_order.is_subscription_extension_order = is_subscription_extension_order
        if is_subscription_extension_order:
            subscription_order = Order.get_by_order_number(
                customer.id, customer.subscription_order_number)
            new_order.next_charge_date = subscription_order.next_charge_date
        added_apps = list()
        should_create_shoptask = False
        for old_item in old_order_items:
            properties = copy_model_properties(old_item)
            new_item = OrderItem(parent=new_order_key, **properties)
            to_put.append(new_item)
            to_delete.append(old_item)
            if hasattr(old_item, 'app_id'):
                added_apps.append(old_item.app_id)
            else:
                should_create_shoptask = True
        to_put.append(new_order)
        db.put(to_put)
        db.delete(to_delete)

        deferred.defer(generate_and_put_order_pdf_and_send_mail,
                       customer,
                       new_order_key,
                       service_user,
                       _transactional=True)

        # No need for signing here, immediately create a charge.
        azzert(new_order.total_amount > 0)
        charge = Charge(parent=new_order_key)
        charge.date = now()
        charge.type = Charge.TYPE_ORDER_DELIVERY
        charge.amount = new_order.amount
        charge.vat_pct = new_order.vat_pct
        charge.vat = new_order.vat
        charge.total_amount = new_order.total_amount
        charge.manager = new_order.manager
        charge.team_id = new_order.team_id
        charge.status = Charge.STATUS_PENDING
        charge.date_executed = now()
        charge.currency_code = team.legal_entity.currency_code
        charge.put()

        # Update the regiomanager statistics so these kind of orders show up in the monthly statistics
        deferred.defer(update_regiomanager_statistic,
                       gained_value=new_order.amount / 100,
                       manager=new_order.manager,
                       _transactional=True)

        # Update the customer service
        si = get_default_service_identity(users.User(customer.service_email))
        si.appIds.extend(added_apps)
        si.put()
        deferred.defer(re_index, si.user, _transactional=True)

        # Update the customer object so the newly added apps are added.
        customer.app_ids.extend(added_apps)
        customer.extra_apps_count += len(added_apps)
        customer.put()

        get_payed(customer.id, new_order, charge)
        # charge the credit card
        channel.send_message(service_user, 'common.billing.orders.update')
        channel_data = {
            'customer': customer.name,
            'no_manager': True,
            'amount': charge.amount / 100,
            'currency': charge.currency
        }
        server_settings = get_server_settings()
        send_to = server_settings.supportWorkers
        send_to.append(MC_DASHBOARD.email())
        channel.send_message(map(users.User, send_to),
                             'shop.monitoring.signed_order',
                             info=channel_data)
        if should_create_shoptask:
            prospect_id = customer.prospect_id
            if prospect_id is None:
                prospect = create_prospect_from_customer(customer)
                prospect_id = prospect.id
            deferred.defer(create_task_for_order,
                           customer.team_id,
                           prospect_id,
                           new_order.order_number,
                           _transactional=True)
        return BoolReturnStatusTO.create(True, None)
Example #8
0
def _replace_subscription_order(order_key, products,
                                paying_subscription_product_codes):
    customer, old_order = db.get([order_key.parent(), order_key])

    if not is_signup_enabled(customer.app_id):
        logging.debug(
            'FREE_SUBSCRIPTIONS - Signup is not enabled for customer %s with app %s',
            customer.name, customer.app_id)
        return

    if customer.service_disabled_at != 0:
        logging.debug('FREE_SUBSCRIPTIONS - Customer %s is disabled',
                      customer.name)
        return

    if old_order.status == Order.STATUS_SIGNED:
        order_items = list(OrderItem.all().ancestor(old_order))
        ordered_product_codes = {i.product_code for i in order_items}
        if not ordered_product_codes.intersection(
                paying_subscription_product_codes):
            logging.debug(
                'FREE_SUBSCRIPTIONS - Customer %s already had a FREE subscription: %s',
                customer.name, list(ordered_product_codes))
            return

        logging.debug(
            'FREE_SUBSCRIPTIONS - Creating new FREE order for customer %s',
            customer.name)
        new_order_items = []
        for old_order_item in OrderItem.list_by_order(order_key):
            product = products[old_order_item.product_code]
            if product.is_subscription_extension:
                new_order_items.append(OrderItemTO.create(old_order_item))
        if new_order_items:
            logging.debug(
                'FREE_SUBSCRIPTIONS - Adding %s old order items: %s',
                len(new_order_items),
                serialize_complex_value(new_order_items, OrderItemTO, True))

        free_item = OrderItemTO()
        free_item.comment = products[
            Product.PRODUCT_FREE_SUBSCRIPTION].default_comment(
                customer.language)

        next_charge_date_time = datetime.datetime.utcfromtimestamp(
            old_order.next_charge_date)
        language = 'nl' if customer.language == 'nl' else 'en'
        next_charge_date = format_date(next_charge_date_time, locale=language)
        if language == 'nl':
            free_item.comment += u'\n\nEr zijn geen abonnementskosten meer! Uw abonnement is omgezet naar een gratis abonnement.'
            if new_order_items:
                free_item.comment += u'\n\nUw uitbreiding voor extra stad/steden is mee overgezet naar het nieuwe abonnement en zal, zoals bij het oude abonnement, op %s aangerekend worden.' % next_charge_date
        else:
            free_item.comment = u'There are no more subscription costs! Your subscription is changed to a free subscription'
            if new_order_items:
                free_item.comment += u'\n\nThe extension for extra cities is also transferred to the new subscription and will be charged at %s, just like you old subscription.' % next_charge_date

        free_item.count = 1
        free_item.id = None
        free_item.number = 0
        free_item.price = 0
        free_item.product = Product.PRODUCT_FREE_SUBSCRIPTION
        free_item.service_visible_in = None
        new_order_items.append(free_item)

        new_order = create_order(customer,
                                 old_order.contact_id,
                                 new_order_items,
                                 replace=True,
                                 regio_manager_user=old_order.manager)
        new_order.next_charge_date = old_order.next_charge_date
        new_order.put()
    else:
        bizz_check(
            customer.subscription_order_number != old_order.order_number,
            'Something is seriously wrong with customer %s (%s)!' %
            (customer.id, customer.name))
        new_order = Order.get_by_order_number(
            customer.id, customer.subscription_order_number)

    if new_order.status == Order.STATUS_UNSIGNED and new_order.total_amount > 0:
        logging.debug('FREE_SUBSCRIPTIONS - Signing order %s for customer %s',
                      new_order.order_number, customer.name)
        sign_order(customer.id,
                   new_order.order_number,
                   signature=u'',
                   no_charge=True)