Example #1
0
 def process_art_show_payment(self, session, id):
     attendee = session.attendee(id)
     charge = Charge(attendee, description="Art show application payment")
     
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent, string_types) else ''
     if message:
         return {'error': message}
     else:
         for app in attendee.art_show_applications:
             app.status = c.PAID  # This needs to accommodate payment cancellations
             send_email.delay(
                 c.ADMIN_EMAIL,
                 c.ART_SHOW_EMAIL,
                 'Art Show Payment Received',
                 render('emails/art_show/payment_notification.txt',
                     {'app': app}, encoding=None),
                 model=app.to_dict('id'))
             send_email.delay(
                 c.ART_SHOW_EMAIL,
                 app.email,
                 'Art Show Payment Received',
                 render('emails/art_show/payment_confirmation.txt',
                     {'app': app}, encoding=None),
                 model=app.to_dict('id'))
         if attendee.paid == c.NOT_PAID:
             attendee.paid = c.HAS_PAID
         session.add(session.create_receipt_item(attendee, charge.amount, "Art show payment", charge.stripe_transaction))
         session.add(attendee)
         session.commit()
         
         return {'stripe_intent': stripe_intent,
                 'success_url': 'edit?id={}&message={}'.format(attendee.art_show_applications[0].id,
                                                               'Your payment has been accepted')}
Example #2
0
 def arbitrary_charge(self,
                      session,
                      id,
                      amount,
                      description,
                      email,
                      return_to='arbitrary_charge_form'):
     charge = Charge(amount=100 * int(amount),
                     description=description,
                     receipt_email=email)
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent,
                                           string_types) else ''
     if message:
         return {'error': message}
     else:
         session.add(
             ArbitraryCharge(
                 amount=charge.dollar_amount,
                 what=charge.description,
                 reg_station=cherrypy.session.get('reg_station')))
         return {
             'stripe_intent':
             stripe_intent,
             'success_url':
             '{}?message={}'.format(return_to,
                                    'Charge successfully processed'),
             'cancel_url':
             'cancel_arbitrary_charge'
         }
Example #3
0
 def purchases_charge(self, session, id, amount, receipt_id):
     receipt = session.art_show_receipt(receipt_id)
     attendee = session.attendee(id)
     charge = Charge(
         attendee,
         amount=amount,
         description='{}ayment for {}\'s art show purchases'.format(
             'P' if int(amount) == receipt.total else 'Partial p',
             attendee.full_name))
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent,
                                           string_types) else ''
     if message:
         return {'error': message}
     else:
         session.add(
             ArtShowPayment(
                 receipt=receipt,
                 amount=charge.amount,
                 type=c.STRIPE,
             ))
         session.commit()
         return {
             'stripe_intent':
             stripe_intent,
             'success_url':
             'pieces_bought?id={}&message={}'.format(
                 attendee.id, 'Charge successfully processed')
         }
Example #4
0
    def take_payment(self, session, id):
        attendee = session.attendee(id)
        charge = Charge(attendee, amount=attendee.amount_unpaid * 100)
        stripe_intent = charge.create_stripe_intent(session)
        message = stripe_intent if isinstance(stripe_intent,
                                              string_types) else ''

        if message:
            return {'error': message}
        else:
            db_attendee = session.query(Attendee).filter_by(
                id=attendee.id).first()
            if db_attendee:
                attendee = db_attendee
            session.add(
                session.create_receipt_item(attendee, charge.amount,
                                            "At-door kiosk payment",
                                            charge.stripe_transaction))
            session.add(attendee)
            session.commit()
            return {
                'stripe_intent': stripe_intent,
                'success_url':
                'register?message={}'.format(c.AT_DOOR_PREPAID_MSG)
            }
 def index(self, message=''):
     if not Charge.unpaid_preregs:
         raise HTTPRedirect('form?message={}',
                            message) if message else HTTPRedirect('form')
     else:
         return {
             'message': message,
             'charge': Charge(listify(Charge.unpaid_preregs.values()))
         }
 def pay(self, session, id, message=''):
     attendee = session.attendee(id)
     if attendee.paid != c.NOT_PAID:
         raise HTTPRedirect('register?message={}', c.AT_DOOR_NOPAY_MSG)
     else:
         return {
             'message': message,
             'attendee': attendee,
             'charge': Charge(attendee, description=attendee.full_name)
         }
Example #7
0
 def test_charge_log_transaction(self, monkeypatch):
     attendee = Attendee()
     monkeypatch.setattr(Attendee, 'amount_unpaid', 10)
     charge = Charge(targets=[attendee], amount=1000, description="Test charge")
     charge.response = stripe.Charge(id=10)
     result = charge.stripe_transaction_from_charge()
     assert result.stripe_id == 10
     assert result.amount == 1000
     assert result.desc == "Test charge"
     assert result.type == c.PAYMENT
     assert result.who == 'non-admin'
Example #8
0
    def process_marketplace_payment(self, session, id):
        attendee = session.attendee(id)
        charge = Charge(
            attendee,
            description="Marketplace application payment for {}".format(
                attendee.full_name))

        stripe_intent = charge.create_stripe_intent(session)
        message = stripe_intent if isinstance(stripe_intent,
                                              string_types) else ''
        if message:
            return {'error': message}
        else:
            if attendee.marketplace_cost:
                for app in attendee.marketplace_applications:
                    cancel_amt = app.amount_unpaid
                    app.amount_paid += app.amount_unpaid
                    send_email.delay(
                        c.ADMIN_EMAIL,
                        c.MARKETPLACE_APP_EMAIL,
                        'Marketplace Payment Received',
                        render('emails/marketplace/payment_notification.txt',
                               {'app': app},
                               encoding=None),
                        model=app.to_dict('id'))
                    send_email.delay(
                        c.MARKETPLACE_APP_EMAIL,
                        app.email_to_address,
                        'Marketplace Payment Received',
                        render('emails/marketplace/payment_confirmation.txt',
                               {'app': app},
                               encoding=None),
                        model=app.to_dict('id'))

            if attendee.paid == c.NOT_PAID:
                attendee.paid = c.HAS_PAID
            session.add(
                session.create_receipt_item(attendee, charge.amount,
                                            "Marketplace payment",
                                            charge.stripe_transaction))
        session.add(attendee)
        session.commit()

        return {
            'stripe_intent':
            stripe_intent,
            'success_url':
            'edit?id={}&message={}'.format(
                attendee.marketplace_applications[0].id,
                'Your payment has been accepted'),
            'cancel_url':
            '../preregistration/cancel_payment?model_id={}&cancel_amt={}'.
            format(attendee.marketplace_applications[0].id, cancel_amt)
        }
Example #9
0
 def index(self, session, message=''):
     if not Charge.unpaid_preregs:
         raise HTTPRedirect('form?message={}',
                            message) if message else HTTPRedirect('form')
     else:
         charge = Charge(listify(Charge.unpaid_preregs.values()))
         for attendee in charge.attendees:
             if attendee.promo_code and attendee.promo_code.group:
                 attendee.group_name = session.query(PromoCode).filter_by(
                     code=attendee.promo_code.code).first().group.name
         return {'message': message, 'charge': charge}
Example #10
0
 def test_charge_log_transaction_no_unpaid(self, monkeypatch):
     group = Group()
     monkeypatch.setattr(Group, 'amount_unpaid', 0)
     charge = Charge(targets=[group], amount=1000,
                     description="Test charge")
     charge.response = stripe.Charge(id=10)
     txn = charge.stripe_transaction_from_charge()
     result = charge.stripe_transaction_for_model(group, txn)
     assert result.group_id == group.id
     assert result.txn_id == txn.id
     assert result.share == 1000
Example #11
0
 def test_charge_log_transaction_attendee(self, monkeypatch):
     attendee = Attendee()
     monkeypatch.setattr(Attendee, 'amount_unpaid', 10)
     charge = Charge(targets=[attendee],
                     description="Test charge")
     charge.response = stripe.Charge(id=10)
     txn = charge.stripe_transaction_from_charge()
     result = charge.stripe_transaction_for_model(attendee, txn)
     assert result.attendee_id == attendee.id
     assert result.txn_id == txn.id
     assert result.share == 1000
Example #12
0
 def test_charge_log_transaction(self):
     attendee = Attendee()
     charge = Charge(targets=[attendee], amount=1000, description="Test charge")
     charge.response = stripe.Charge(id=10)
     result = charge.stripe_transaction_from_charge()
     assert result.stripe_id == 10
     assert result.amount == 1000
     assert result.desc == "Test charge"
     assert result.type == c.PAYMENT
     assert result.who == 'non-admin'
     assert result.fk_id == attendee.id
     assert result.fk_model == attendee.__class__.__name__
Example #13
0
 def pay(self, session, id, message=''):
     attendee = session.attendee(id)
     if attendee.paid != c.NOT_PAID:
         raise HTTPRedirect(
             'register?message={}',
             'You are already paid (or registered for a free badge) '
             'and should proceed to the preregistration desk to pick up your badge')
     else:
         return {
             'message': message,
             'attendee': attendee,
             'charge': Charge(attendee, description=attendee.full_name)
         }
    def attendee_donation_form(self, session, id, message=''):
        attendee = session.attendee(id)
        if attendee.amount_unpaid <= 0:
            raise HTTPRedirect('confirm?id={}', id)
        if 'attendee_donation_form' not in attendee.payment_page:
            raise HTTPRedirect(attendee.payment_page)

        return {
            'message': message,
            'attendee': attendee,
            'charge': Charge(
                attendee,
                description='{}{}'.format(attendee.full_name, '' if attendee.overridden_price else ' kicking in extra'))
        }
    def add_group_members(self, session, id, count):
        group = session.group(id)
        if int(count
               ) < group.min_badges_addable and not group.is_in_grace_period:
            raise HTTPRedirect(
                'group_members?id={}&message={}', group.id,
                'This group cannot add fewer than {} badges'.format(
                    group.min_badges_addable))

        charge = Charge(group,
                        amount=100 * int(count) * group.new_badge_cost,
                        description='{} extra badges for {}'.format(
                            count, group.name))

        return {'count': count, 'group': group, 'charge': charge}
    def process_free_prereg(self, session):
        charge = Charge(listify(Charge.unpaid_preregs.values()))
        if charge.total_cost <= 0:
            for attendee in charge.attendees:
                session.add(attendee)

            for group in charge.groups:
                session.add(group)

            Charge.unpaid_preregs.clear()
            Charge.paid_preregs.extend(charge.targets)
            raise HTTPRedirect('paid_preregistrations?payment_received={}', charge.dollar_amount)
        else:
            message = "These badges aren't free! Please pay for them."
            raise HTTPRedirect('index?message={}', message)
Example #17
0
    def add_promo_codes(self, session, id, count):
        group = session.promo_code_group(id)
        if int(count
               ) < group.min_badges_addable and not group.is_in_grace_period:
            raise HTTPRedirect(
                'group_promo_codes?id={}&message={}', group.id,
                'You must add at least {} codes'.format(
                    group.min_badges_addable))

        charge = Charge(group.buyer,
                        amount=100 * int(count) * c.get_group_price(),
                        description='{} extra badge{} for {}'.format(
                            count, 's' if int(count) > 1 else '', group.name))

        return {'count': count, 'group': group, 'charge': charge}
Example #18
0
    def arbitrary_charge_form(self, message='', amount=None, description=''):
        charge = None
        if amount is not None:
            if not amount.isdigit() or not (1 <= int(amount) <= 999):
                message = 'Amount must be a dollar amount between $1 and $999'
            elif not description:
                message = "You must enter a brief description of what's being sold"
            else:
                charge = Charge(amount=100 * int(amount), description=description)

        return {
            'charge': charge,
            'message': message,
            'amount': amount,
            'description': description
        }
Example #19
0
    def manual_reg_charge(self, session, id):
        attendee = session.attendee(id)
        charge = Charge(attendee, amount=attendee.amount_unpaid * 100)
        stripe_intent = charge.create_stripe_intent(session)
        message = stripe_intent if isinstance(stripe_intent,
                                              string_types) else ''

        if message:
            return {'error': message}
        else:
            attendee.payment_method = c.MANUAL
            session.add(
                session.create_receipt_item(attendee, charge.amount,
                                            "At-door desk payment",
                                            charge.stripe_transaction))

            session.merge(attendee)
            session.commit()
            return {'stripe_intent': stripe_intent, 'success_url': ''}
    def sales_charge_form(self,
                          message='',
                          amount=None,
                          description='',
                          sale_id=None):
        charge = None
        if amount is not None:
            if not description:
                message = "You must enter a brief description " \
                          "of what's being sold"
            else:
                charge = Charge(amount=int(100 * float(amount)),
                                description=description)

        return {
            'charge': charge,
            'message': message,
            'amount': amount,
            'description': description,
            'sale_id': sale_id
        }
    def group_members(self, session, id, message='', **params):
        group = session.group(id)
        charge = Charge(group)
        if group.status != c.APPROVED and 'name' in params:
            # Both the Attendee class and Group class have identically named
            # address fields. In order to distinguish the two sets of address
            # fields in the params, the Group fields are prefixed with "group_"
            # when the form is submitted. To prevent instantiating the Group object
            # with the Attendee's address fields, we must clone the params and
            # rename all the "group_" fields.
            group_params = dict(params)
            for field_name in [
                    'country', 'region', 'zip_code', 'address1', 'address2',
                    'city'
            ]:
                group_params[field_name] = params.get(
                    'group_{}'.format(field_name), '')

            group.apply(group_params, restricted=True)
            message = check(group, prereg=True)
            if message:
                session.rollback()
            else:
                session.commit()
                if group.is_dealer:
                    send_email.delay(
                        c.MARKETPLACE_EMAIL,
                        c.MARKETPLACE_EMAIL,
                        'Dealer Application Changed',
                        render('emails/dealers/appchange_notification.html',
                               {'group': group},
                               encoding=None),
                        'html',
                        model=group.to_dict('id'))

                message = 'Thank you! Your application has been updated.'

            raise HTTPRedirect('group_members?id={}&message={}', group.id,
                               message)
        return {'group': group, 'charge': charge, 'message': message}
Example #22
0
 def sales_charge(self, session, id, amount, description):
     charge = Charge(amount=100 * float(amount), description=description)
     stripe_intent = charge.create_stripe_intent(session)
     message = stripe_intent if isinstance(stripe_intent,
                                           string_types) else ''
     if message:
         return {'error': message}
     else:
         session.add(
             ArbitraryCharge(
                 amount=charge.dollar_amount,
                 what=charge.description,
             ))
         return {
             'stripe_intent':
             stripe_intent,
             'success_url':
             'sales_charge_form?message={}'.format(
                 'Charge successfully processed'),
             'cancel_url':
             '../merch_admin/cancel_arbitrary_charge'
         }
    def group_members(self, session, id, message='', **params):
        group = session.group(id)
        charge = Charge(group)
        if cherrypy.request.method == 'POST':
            # Both the Attendee class and Group class have identically named
            # address fields. In order to distinguish the two sets of address
            # fields in the params, the Group fields are prefixed with "group_"
            # when the form is submitted. To prevent instantiating the Group object
            # with the Attendee's address fields, we must clone the params and
            # rename all the "group_" fields.
            group_params = dict(params)
            for field_name in ['country', 'region', 'zip_code', 'address1', 'address2', 'city']:
                group_params[field_name] = params.get('group_{}'.format(field_name), '')

            group.apply(group_params, restricted=True)
            message = check(group, prereg=True)
            if message:
                session.rollback()
            else:
                session.commit()
                if group.is_dealer:
                    send_email.delay(
                        c.MARKETPLACE_EMAIL,
                        c.MARKETPLACE_EMAIL,
                        '{} Changed'.format(c.DEALER_APP_TERM.title()),
                        render('emails/dealers/appchange_notification.html', {'group': group}, encoding=None),
                        'html',
                        model=group.to_dict('id'))

                message = 'Thank you! Your application has been updated.'

            raise HTTPRedirect('group_members?id={}&message={}', group.id, message)
        return {
            'group':   group,
            'upgraded_badges': len([a for a in group.attendees if a.badge_type in c.BADGE_TYPE_PRICES]),
            'charge':  charge,
            'message': message
        }
Example #24
0
    def edit(self, session, message='', **params):
        app = session.marketplace_application(params,
                                              restricted=True,
                                              ignore_csrf=True)
        return_to = params['return_to'] \
            if 'return_to' in params else '/marketplace/edit'
        if 'id' not in params:
            message = 'Invalid marketplace application ID. ' \
                      'Please try going back in your browser.'

        if cherrypy.request.method == 'POST':
            message = check(app, prereg=True)
            if not message:
                session.add(app)
                session.commit(
                )  # Make sure we update the DB or the email will be wrong!
                send_email.delay(
                    c.MARKETPLACE_APP_EMAIL,
                    app.email,
                    'Marketplace Application Updated',
                    render('emails/marketplace/appchange_notification.html',
                           {'app': app},
                           encoding=None),
                    'html',
                    model=app.to_dict('id'))
                raise HTTPRedirect('..{}?id={}&message={}', return_to, app.id,
                                   'Your application has been updated')
            else:
                session.rollback()

        return {
            'message': message,
            'app': app,
            'return_to': 'edit',
            'charge': Charge(app.attendee)
        }
    def pieces_bought(self, session, id, search_text='', message='', **params):
        try:
            receipt = session.art_show_receipt(id)
        except:
            attendee = session.attendee(id)
            if not attendee.art_show_receipt:
                receipt = ArtShowReceipt(attendee=attendee)
                session.add(receipt)
                session.commit()
            else:
                receipt = attendee.art_show_receipt
        else:
            attendee = receipt.attendee

        must_choose = False
        unclaimed_pieces = []
        unpaid_pieces = []
        charge = None

        if search_text:
            if re.match('\w+-[0-9]+', search_text):
                artist_id, piece_id = search_text.split('-')
                pieces = session.query(ArtShowPiece).join(
                    ArtShowPiece.app).filter(
                        ArtShowPiece.piece_id == int(piece_id),
                        ArtShowApplication.artist_id == artist_id.upper())
            else:
                pieces = session.query(ArtShowPiece).filter(
                    ArtShowPiece.name.ilike('%{}%'.format(search_text)))

            unclaimed_pieces = pieces.filter(ArtShowPiece.buyer == None,
                                             ArtShowPiece.status != c.RETURN)
            unclaimed_pieces = [
                piece for piece in unclaimed_pieces if piece.sale_price > 0
            ]
            unpaid_pieces = pieces.join(ArtShowReceipt).filter(
                ArtShowReceipt.closed != None, ArtShowPiece.status != c.PAID)
            unpaid_pieces = [
                piece for piece in unpaid_pieces if piece.sale_price > 0
            ]

            if pieces.count() == 0:
                message = "No pieces found with ID or title {}.".format(
                    search_text)
            elif len(unclaimed_pieces) == 0 and len(unpaid_pieces) == 0:
                if pieces.count() == 1:
                    msg_piece = pieces.one()
                    if msg_piece.receipt == receipt:
                        message = "That piece ({}) is already on this receipt.".format(
                            msg_piece.artist_and_piece_id)
                    elif msg_piece.sale_price <= 0:
                        message = "That piece ({}) doesn't have a valid sale price." \
                            .format(msg_piece.artist_and_piece_id)
                    elif msg_piece.status == c.RETURN:
                        message = "That piece ({}) is marked {}.".format(
                            msg_piece.artist_and_piece_id,
                            msg_piece.status_label)
                    elif msg_piece in attendee.art_show_purchases:
                        message = "That piece ({}) was already sold to this buyer."\
                            .format(msg_piece.artist_and_piece_id)
                    else:
                        message = "That piece ({}) was already sold to another buyer."\
                            .format(msg_piece.artist_and_piece_id)
                else:
                    message = "None of the matching pieces for '{}' can be claimed.".format(
                        search_text)
            elif len(unclaimed_pieces) > 1 or (len(unclaimed_pieces) == 0
                                               and len(unpaid_pieces) > 1):
                message = "There were multiple pieces found matching '{}.' Please choose one.".format(
                    search_text)
                must_choose = True

            if not message:
                if len(unclaimed_pieces) == 0 and len(unpaid_pieces) == 1:
                    piece = unpaid_pieces[0]
                elif len(unclaimed_pieces) == 1:
                    piece = unclaimed_pieces[0]
                else:
                    message = "Something went wrong! Try again?"

                if not message:
                    piece.receipt = receipt
                    session.add(piece)
                    message = 'Piece {} successfully claimed'.format(
                        piece.artist_and_piece_id)

            if not must_choose:
                raise HTTPRedirect('pieces_bought?id={}&message={}',
                                   receipt.id, message)
        elif 'amount' in params:
            if params['amount']:
                amount = int(Decimal(params['amount']) * 100)
            else:
                amount = receipt.owed

            charge = Charge(
                targets=[attendee],
                amount=amount,
                description='{}ayment for {}\'s art show purchases'.format(
                    'P' if amount == receipt.total else 'Partial p',
                    attendee.full_name))

        return {
            'receipt': receipt,
            'message': message,
            'must_choose': must_choose,
            'pieces': unclaimed_pieces or unpaid_pieces,
            'charge': charge,
        }
Example #26
0
 def test_charge_log_transaction_no_model(self):
     stripe.Charge.create = Mock(return_value=1)
     Charge.stripe_transaction_from_charge = Mock()
     charge = Charge(amount=1000, description="Test charge")
     Charge.charge_cc(charge, Mock(), 1)
     assert not Charge.stripe_transaction_from_charge.called
Example #27
0
 def test_charge_one_email(self):
     attendee = Attendee(email='*****@*****.**')
     charge = Charge(targets=[attendee])
     assert charge.receipt_email == attendee.email
Example #28
0
 def test_charge_group_leader_email(self):
     attendee = Attendee(email='*****@*****.**')
     group = Group(attendees=[attendee])
     charge = Charge(targets=[group])
     assert charge.receipt_email == attendee.email
Example #29
0
 def test_charge_no_email(self):
     charge = Charge(targets=[Group()])
     assert charge.receipt_email is None
Example #30
0
 def test_charge_first_email(self):
     attendee = Attendee(email='*****@*****.**')
     charge = Charge(targets=[attendee, Attendee(email='*****@*****.**'), Attendee(email='*****@*****.**')])
     assert charge.receipt_email == attendee.email