def test_ticket_with_different_discount_code(db): ticket = TicketSubFactory() discount = DiscountCodeTicketSubFactory(tickets=[]) db.session.commit() with pytest.raises(UnprocessableEntityError, match='Invalid Discount Code'): calculate_order_amount([{'id': ticket.id}], discount.id)
def _expect_donation_error(ticket_dict): with pytest.raises( UnprocessableEntityError, match='Price for donation ticket should be present and within range ' '10.0 to 20.0', ): calculate_order_amount(ticket_dict)
def test_ticket_with_deleted_discount_code(db): ticket = TicketSubFactory() discount = DiscountCodeTicketSubFactory(deleted_at=datetime.now(), tickets=[ticket]) db.session.commit() with pytest.raises(ObjectNotFound): calculate_order_amount([{'id': ticket.id}], discount.id)
def test_multiple_tickets_different_event(db): ticket1 = TicketSubFactory() ticket2 = TicketSubFactory() db.session.commit() ticket_dict = _create_ticket_dict([ticket1, ticket2], [1, 2]) with pytest.raises(UnprocessableEntityError, match=r".*All tickets must belong to same event.*"): calculate_order_amount(ticket_dict)
def test_no_amount(db): amount_data = calculate_order_amount([]) assert amount_data['total'] == 0.0 assert amount_data['tax'] is None assert amount_data['discount'] == 0.0 assert amount_data['tickets'] == []
def test_multiple_tickets(db): ticket = TicketSubFactory(price=50) ticket2 = TicketSubFactory(price=12.5, event=ticket.event) ticket3 = TicketSubFactory(price=233.15, event=ticket.event) db.session.commit() tickets = _create_ticket_dict([ticket, ticket2, ticket3], [3, 1, 2]) amount_data = calculate_order_amount(tickets) assert amount_data['total'] == 628.8 assert amount_data['tax_included'] is None assert amount_data['tax'] == 0.0 assert amount_data['discount'] == 0.0 ticket_dict = amount_data['tickets'][0] assert ticket_dict['id'] == ticket.id assert ticket_dict['name'] == ticket.name assert ticket_dict['price'] == ticket.price assert ticket_dict['quantity'] == 3 assert ticket_dict['ticket_fee'] == 0.0 assert ticket_dict['sub_total'] == 150.0 assert amount_data['tickets'][-1]['id'] == ticket3.id assert amount_data['tickets'][-1]['price'] == ticket3.price assert amount_data['tickets'][-1]['quantity'] == 2 assert amount_data['tickets'][-1]['sub_total'] == 466.3
def create_order(): data, errors = OrderAmountInputSchema().load(request.get_json()) if errors: return make_response(jsonify(errors), 422) tickets_dict = data['tickets'] order_amount = calculate_order_amount(tickets_dict, data.get('discount_code')) ticket_ids = {ticket['id'] for ticket in tickets_dict} ticket_map = {int(ticket['id']): ticket for ticket in tickets_dict} tickets = ( Ticket.query.filter_by(deleted_at=None).filter(Ticket.id.in_(ticket_ids)).all() ) if not tickets: raise UnprocessableEntityError( {'source': 'tickets'}, "Tickets missing in Order request", ) event = tickets[0].event try: attendees = [] for ticket in tickets: for _ in range(ticket_map[ticket.id]['quantity']): ticket.raise_if_unavailable() attendees.append( TicketHolder(firstname='', lastname='', ticket=ticket, event=event) ) db.session.commit() except Exception as e: db.session.rollback() raise e validate_attendees({attendee.id for attendee in attendees}) if data.get('amount') is not None and ( current_user.is_staff or has_access('is_coorganizer', event_id=event.id) ): # If organizer or admin has overrided the amount of order order_amount['total'] = data['amount'] order = Order( amount=order_amount['total'], event=event, discount_code_id=data.get('discount_code'), ticket_holders=attendees, ) db.session.commit() order.populate_and_save() order_tickets = OrderTicket.query.filter_by(order_id=order.id).all() for order_ticket in order_tickets: ticket_info = ticket_map[order_ticket.ticket.id] order_ticket.price = ticket_info.get('price') save_to_db(order_ticket) return OrderSchema().dump(order)
def test_tax_included_with_discount(db): discount_code = DiscountCodeTicketSubFactory(type='percent', value=10.0, tickets=[]) tickets_dict = _create_taxed_tickets(db, discount_code=discount_code) amount_data = calculate_order_amount(tickets_dict, discount_code) assert amount_data['sub_total'] == 4021.87 assert amount_data['total'] == 4021.87 assert amount_data['tax_included'] is True _assert_tax_data_discount(amount_data)
def calculate_amount(): data = request.get_json() tickets = data['tickets'] discount_code = None if 'discount-code' in data: discount_code_id = data['discount-code'] discount_code = safe_query(db, DiscountCode, 'id', discount_code_id, 'id') if not TicketingManager.match_discount_quantity(discount_code, tickets, None): return UnprocessableEntityError({'source': 'discount-code'}, 'Discount Usage Exceeded').respond() return jsonify(calculate_order_amount(tickets, discount_code))
def test_tax_excluded(db): tickets_dict = _create_taxed_tickets(db, tax_included=False) amount_data = calculate_order_amount(tickets_dict) assert amount_data['sub_total'] == 4441.3 assert amount_data['total'] == pytest.approx(4441.3 + 799.43) assert amount_data['tax_included'] is False assert amount_data['tax_percent'] == 18.0 assert amount_data['tax'] == 799.43 assert amount_data['discount'] == 0.0
def test_tax_included(db): tickets_dict = _create_taxed_tickets(db) amount_data = calculate_order_amount(tickets_dict) assert amount_data['sub_total'] == 4441.3 assert amount_data['total'] == 4441.3 assert amount_data['tax_included'] is True assert amount_data['tax_percent'] == 18.0 assert amount_data['tax'] == 799.43 assert amount_data['discount'] == 0.0
def test_no_amount_with_discount(db): ticket = TicketSubFactory(price=100.0) discount_code = DiscountCodeTicketSubFactory( type='percent', value=10.0, tickets=[ticket] ) db.session.commit() amount_data = calculate_order_amount([], discount_code.id) assert amount_data['total'] == 0.0 assert amount_data['tax'] is None assert amount_data['discount'] == 0.0 assert amount_data['tickets'] == []
def test_single_ticket(db): ticket = TicketSubFactory(price=10) db.session.commit() amount_data = calculate_order_amount([{'id': ticket.id}]) assert amount_data['total'] == 10.0 assert amount_data['tax'] is None assert amount_data['discount'] == 0.0 ticket_dict = amount_data['tickets'][0] assert ticket_dict['id'] == ticket.id assert ticket_dict['name'] == ticket.name assert ticket_dict['price'] == ticket.price assert ticket_dict['quantity'] == 1 assert ticket_dict['ticket_fee'] == 0.0 assert ticket_dict['sub_total'] == 10.0
def test_donation_ticket(db): ticket_dict = _create_donation_tickets(db) ticket_dict[0]['price'] = 15.13 amount_data = calculate_order_amount(ticket_dict) assert amount_data['total'] == 80.26 assert amount_data['tax'] is None assert amount_data['discount'] == 0.0 ticket_dict = amount_data['tickets'][0] assert ticket_dict['price'] == 10 assert ticket_dict['quantity'] == 3 assert ticket_dict['sub_total'] == 30.0 assert amount_data['tickets'][-1]['price'] == 15.13 assert amount_data['tickets'][-1]['quantity'] == 2 assert amount_data['tickets'][-1]['sub_total'] == 30.26
def test_discount_code_amount_type(db): ticket = TicketSubFactory(price=100.0) discount_code = DiscountCodeTicketSubFactory( type='amount', value=50.0, tickets=[ticket] ) db.session.commit() amount_data = calculate_order_amount([{'id': ticket.id}], discount_code.id) assert amount_data['total'] == 50.0 assert amount_data['discount'] == 50.0 ticket_dict = amount_data['tickets'][0] assert ticket_dict['sub_total'] == 50.0 assert ticket_dict['discount']['total'] == 50.0 assert ticket_dict['discount']['amount'] == 50.0 assert ticket_dict['discount']['percent'] == 50.0 assert ticket_dict['discount']['code'] == discount_code.code
def create_order(): data, errors = OrderAmountInputSchema().load(request.get_json()) if errors: return make_response(jsonify(errors), 422) tickets_dict = data['tickets'] order_amount = calculate_order_amount(tickets_dict, data.get('discount_code')) ticket_ids = {ticket['id'] for ticket in tickets_dict} ticket_map = {int(ticket['id']): ticket for ticket in tickets_dict} tickets = ( Ticket.query.filter_by(deleted_at=None).filter(Ticket.id.in_(ticket_ids)).all() ) if not tickets: raise UnprocessableEntityError( {'source': 'tickets'}, "Tickets missing in Order request", ) event = tickets[0].event try: attendees = [] for ticket in tickets: for _ in range(ticket_map[ticket.id]['quantity']): ticket.raise_if_unavailable() attendees.append( TicketHolder(firstname='', lastname='', ticket=ticket, event=event) ) db.session.commit() except Exception as e: db.session.rollback() raise e validate_attendees({attendee.id for attendee in attendees}) order = Order( amount=order_amount['total'], event=event, discount_code_id=data.get('discount_code'), ticket_holders=attendees, ) db.session.commit() order.populate_and_save() return OrderSchema().dumps(order)
def test_multiple_tickets_discount(db): ticket_a = TicketSubFactory(price=50.0) ticket_b = TicketSubFactory(price=495.8, event=ticket_a.event) ticket_c = TicketSubFactory(price=321.3, event=ticket_a.event) # Deliberately add price to free ticket ticket_d = TicketSubFactory(price=500.0, event=ticket_a.event, type='free') discount = DiscountCodeTicketSubFactory(type='percent', value=50.0, tickets=[ticket_a, ticket_b]) DiscountCodeTicketSubFactory(type='amount', value=100.0, tickets=[ticket_c]) db.session.commit() tickets_dict = _create_ticket_dict( [ticket_a, ticket_b, ticket_c, ticket_d], [2, 3, 1, 2]) amount_data = calculate_order_amount(tickets_dict, discount.id) assert amount_data['total'] == 1115.0 assert amount_data['discount'] == 793.7 assert amount_data['tickets'][0]['quantity'] == 2 assert amount_data['tickets'][0]['price'] == 50.0 assert amount_data['tickets'][0]['sub_total'] == 50.0 assert amount_data['tickets'][0]['discount']['total'] == 50.0 assert amount_data['tickets'][0]['discount']['amount'] == 25.0 assert amount_data['tickets'][0]['discount']['percent'] == 50.0 assert amount_data['tickets'][1]['quantity'] == 3 assert amount_data['tickets'][1]['price'] == 495.8 assert amount_data['tickets'][1]['sub_total'] == 743.7 assert amount_data['tickets'][1]['discount']['total'] == 743.7 assert amount_data['tickets'][1]['discount']['amount'] == 247.9 assert amount_data['tickets'][1]['discount']['percent'] == 50.0 assert amount_data['tickets'][2]['quantity'] == 1 assert amount_data['tickets'][2]['price'] == 321.3 assert amount_data['tickets'][2]['sub_total'] == 321.3 assert amount_data['tickets'][2]['discount'] is None
def test_discount_code(db): ticket = TicketSubFactory(price=100.0) discount_code = DiscountCodeTicketSubFactory( type='percent', value=10.0, tickets=[ticket] ) db.session.commit() amount_data = calculate_order_amount([{'id': ticket.id}], discount_code.id) assert amount_data['total'] == 90.0 assert amount_data['tax'] is None assert amount_data['discount'] == 10.0 ticket_dict = amount_data['tickets'][0] assert ticket_dict['id'] == ticket.id assert ticket_dict['name'] == ticket.name assert ticket_dict['price'] == ticket.price assert ticket_dict['quantity'] == 1 assert ticket_dict['ticket_fee'] == 0.0 assert ticket_dict['sub_total'] == 90.0 assert ticket_dict['discount']['total'] == 10.0 assert ticket_dict['discount']['amount'] == 10.0 assert ticket_dict['discount']['percent'] == 10.0 assert ticket_dict['discount']['code'] == discount_code.code
def calculate_amount(): data, errors = OrderAmountInputSchema().load(request.get_json()) if errors: return make_response(jsonify(errors), 422) return jsonify( calculate_order_amount(data['tickets'], data.get('discount_code')))
def create_order(): data = request.get_json() tickets, discount_code = calculate_order_amount_wrapper(data) attendee = data['attendee'] for attribute in attendee: attendee[attribute.replace('-', '_')] = attendee.pop(attribute) schema = AttendeeSchema() json_api_attendee = { "data": { "attributes": data['attendee'], "type": "attendee" } } result = schema.load(json_api_attendee) if result.errors: return make_response(jsonify(result.errors), 422) ticket_ids = {int(ticket['id']) for ticket in tickets} quantity = {int(ticket['id']): ticket['quantity'] for ticket in tickets} ticket_list = (db.session.query(Ticket).filter( Ticket.id.in_(ticket_ids)).filter_by(event_id=data['event_id'], deleted_at=None).all()) ticket_ids_found = { ticket_information.id for ticket_information in ticket_list } tickets_not_found = ticket_ids - ticket_ids_found if tickets_not_found: return make_response( jsonify( status='Order Unsuccessful', error='Tickets with id {} were not found in Event {}.'.format( tickets_not_found, data['event_id']), ), 404, ) for ticket_info in ticket_list: if (ticket_info.quantity - get_count( db.session.query(TicketHolder.id).filter_by( ticket_id=int(ticket_info.id), deleted_at=None))) < quantity[ticket_info.id]: return make_response( jsonify(status='Order Unsuccessful', error='Ticket already sold out.'), 409, ) attendee_list = [] for ticket in tickets: for ticket_amount in range(ticket['quantity']): attendee = TicketHolder(**result[0], event_id=int(data['event_id']), ticket_id=int(ticket['id'])) db.session.add(attendee) attendee_list.append(attendee) ticket_pricing = calculate_order_amount(tickets, discount_code) if not has_access('is_coorganizer', event_id=data['event_id']): data['status'] = 'initializing' # create on site attendees # check if order already exists for this attendee. # check for free tickets and verified user order = Order( amount=ticket_pricing['total_amount'], user_id=current_user.id, event_id=int(data['event_id']), status=data['status'], ) db.session.add(order) db.session.commit() db.session.refresh(order) order_tickets = {} for holder in attendee_list: holder.order_id = order.id db.session.add(holder) if not order_tickets.get(holder.ticket_id): order_tickets[holder.ticket_id] = 1 else: order_tickets[holder.ticket_id] += 1 create_pdf_tickets_for_holder(order) for ticket in order_tickets: od = OrderTicket(order_id=order.id, ticket_id=ticket, quantity=order_tickets[ticket]) db.session.add(od) order.quantity = order.tickets_count db.session.add(order) db.session.commit() db.session.refresh(order) order_schema = OrderSchema() return order_schema.dump(order)
def calculate_amount(): data = request.get_json() tickets, discount_code = calculate_order_amount_wrapper(data) return jsonify(calculate_order_amount(tickets, discount_code))
def calculate_amount(): data = request.get_json() return jsonify( calculate_order_amount(data['tickets'], data.get('discount-code')))
def test_ticket_of_deleted_event(db): ticket = TicketSubFactory(event__deleted_at=datetime.now()) db.session.commit() with pytest.raises(ObjectNotFound): calculate_order_amount([{'id': ticket.id}])