def test_coupon_should_not_get_invalidated(self, session, coupons):
        """ Coupons that haven't expired should remain valid. """
        may_29_2015 = datetime.datetime(2015, 05, 29, 0, 0, 0)
        may_29_2015 = pytz.utc.localize(may_29_2015)

        june_29_2015 = datetime.datetime(2015, 06, 29, 0, 0, 0)
        june_29_2015 = pytz.utc.localize(june_29_2015)

        Coupon.expire_old_coupons(may_29_2015)

        coupon = Coupon.query.filter(Coupon.redeem_by == june_29_2015)
        assert coupon.first().valid is True
    def test_coupon_should_get_invalidated(self, session, coupons):
        """ Coupons that are not redeemable should expire. """
        may_29_2015 = datetime.datetime(2015, 05, 29, 0, 0, 0)
        may_29_2015 = pytz.utc.localize(may_29_2015)

        june_29_2015 = datetime.datetime(2015, 06, 29, 0, 0, 0)
        june_29_2015 = pytz.utc.localize(june_29_2015)

        Coupon.expire_old_coupons(june_29_2015)

        coupon = Coupon.query.filter(Coupon.redeem_by == may_29_2015)
        assert coupon.first().valid is False
Example #3
0
def coupons(page):
    search_form = SearchForm()
    bulk_form = BulkDeleteForm()

    sort_by = Coupon.sort_by(request.args.get('sort', 'created_on'),
                             request.args.get('direction', 'desc'))
    order_values = '{0} {1}'.format(sort_by[0], sort_by[1])

    paginated_coupons = Coupon.query \
        .filter(Coupon.search(request.args.get('q', ''))) \
        .order_by(text(order_values)) \
        .paginate(page, 20, True)

    return render_template('admin/coupon/index.jinja2',
                           form=search_form, bulk_form=bulk_form,
                           coupons=paginated_coupons)
def expire_old_coupons():
    """
    Invalidate coupons that are past their redeem date.

    :return: Result of updating the records
    """
    return Coupon.expire_old_coupons()
    def test_random_coupon_code(self):
        """ Random coupon code is created. """
        from catwatch.blueprints.billing.tasks import expire_old_coupons

        expire_old_coupons.delay()

        random_coupon = Coupon.random_coupon_code()
        assert len(random_coupon) == 14
        assert random_coupon.isupper()
def delete_coupons(ids):
    """
    Delete coupons both on the payment gateway and locally.

    :param ids: List of ids to be deleted
    :type ids: list
    :return: int
    """
    return Coupon.bulk_delete(ids)
def coupons():
    """
    Create random coupons (this actually creates them on Stripe too).
    """
    data = []

    for i in range(0, 5):
        random_pct = random.random()
        duration = random.choice(Coupon.DURATION.keys())

        # Create a fake unix timestamp in the future.
        redeem_by = fake.date_time_between(start_date='now',
                                           end_date='+1y').strftime('%s')

        # Bulk inserts need the same columns, so let's setup a few nulls.
        params = {
            'code': Coupon.random_coupon_code(),
            'duration': duration,
            'percent_off': None,
            'amount_off': None,
            'currency': None,
            'redeem_by': None,
            'max_redemptions': None,
            'duration_in_months': None,
        }

        if random_pct >= 0.5:
            params['percent_off'] = random.randint(1, 100)
            params['max_redemptions'] = random.randint(15, 50)
        else:
            params['amount_off'] = random.randint(1, 1337)
            params['currency'] = 'usd'

        if random_pct >= 0.75:
            params['redeem_by'] = redeem_by

        if duration == 'repeating':
            duration_in_months = random.randint(1, 12)
            params['duration_in_months'] = duration_in_months

        PaymentCoupon.create(**params)

        # Our database requires a Date object, not a unix timestamp.
        if redeem_by:
            params['redeem_by'] = datetime.utcfromtimestamp(float(redeem_by)) \
                .strftime('%Y-%m-%dT%H:%M:%S Z')

        if 'id' in params:
            params['code'] = params.get('id')
            del params['id']

        data.append(params)

    return _bulk_insert(Coupon, data, 'coupons')
def coupons():
    """
    Create random coupons.
    """
    data = []

    for i in range(0, 5):
        random_pct = random.random()
        duration = random.choice(Coupon.DURATION.keys())

        # Create a fake unix timestamp in the future.
        redeem_by = fake.date_time_between(start_date='now',
                                           end_date='+1y').strftime('%s')

        # Bulk inserts need the same columns, so let's setup a few nulls.
        params = {
            'code': Coupon.random_coupon_code(),
            'duration': duration,
            'percent_off': None,
            'amount_off': None,
            'currency': None,
            'redeem_by': None,
            'max_redemptions': None,
            'duration_in_months': None,
        }

        if random_pct >= 0.5:
            params['percent_off'] = random.randint(1, 100)
            params['max_redemptions'] = random.randint(15, 50)
        else:
            params['amount_off'] = random.randint(1, 1337)
            params['currency'] = 'usd'

        if random_pct >= 0.75:
            params['redeem_by'] = redeem_by

        if duration == 'repeating':
            duration_in_months = random.randint(1, 12)
            params['duration_in_months'] = duration_in_months

        PaymentCoupon.create(**params)

        # Our database requires a Date object, not a unix timestamp.
        if redeem_by:
            params['redeem_by'] = datetime.utcfromtimestamp(float(redeem_by)) \
                .strftime('%Y-%m-%dT%H:%M:%S Z')

        if 'id' in params:
            params['code'] = params.get('id')
            del params['id']

        data.append(params)

    return _bulk_insert(Coupon, data, 'coupons')
def coupon_code():
    code = request.form.get('coupon_code')
    if code is None:
        return render_json(422,
                           {'error': _('Discount code cannot be processed.')})

    coupon = Coupon.find_by_code(code)
    if coupon is None:
        return render_json(404, {'error': _('Discount code not found.')})

    return render_json(200, {'data': coupon.serialize()})
Example #10
0
def coupon_code():
    code = request.form.get('coupon_code')
    if code is None:
        return render_json(422,
                           {'error': _('Discount code cannot be processed.')})

    coupon = Coupon.find_by_code(code)
    if coupon is None:
        return render_json(404, {'error': _('Discount code not found.')})

    return render_json(200, {'data': coupon.serialize()})
Example #11
0
def coupons_new():
    coupon = Coupon()
    form = CouponForm(obj=coupon)

    if form.validate_on_submit():
        form.populate_obj(coupon)

        params = {
            'code': coupon.code,
            'duration': coupon.duration,
            'percent_off': coupon.percent_off,
            'amount_off': coupon.amount_off,
            'currency': coupon.currency,
            'redeem_by': coupon.redeem_by,
            'max_redemptions': coupon.max_redemptions,
            'duration_in_months': coupon.duration_in_months,
        }

        if Coupon.create(params):
            flash(_('Coupon has been created successfully.'), 'success')
            return redirect(url_for('admin.coupons'))

    return render_template('admin/coupon/new.jinja2', form=form, coupon=coupon)
Example #12
0
def coupons_bulk_delete():
    form = BulkDeleteForm()

    if form.validate_on_submit():
        ids = Coupon.get_bulk_action_ids(request.form.get('scope'),
                                         request.form.getlist('bulk_ids'),
                                         query=request.args.get('q', ''))

        # Prevent circular imports.
        from catwatch.blueprints.billing.tasks import delete_coupons

        delete_coupons.delay(ids)

        flash(_n('%(num)d coupon was scheduled to be deleted.',
                 '%(num)d coupons were scheduled to be deleted.',
                 num=len(ids)), 'success')
    else:
        flash(_('No coupons were deleted, something went wrong.'), 'error')

    return redirect(url_for('admin.coupons'))
    def test_coupon_without_redeem_by_should_be_valid(self, session, coupons):
        """ Coupons that do not expire should be valid. """
        Coupon.expire_old_coupons()

        coupon = Coupon.query.filter(Coupon.redeem_by.is_(None))
        assert coupon.first().valid is True