def psp_update(client_id, account_shortname, psp_name, psp_data): """Updates the psp of the account""" account = lookup_account_by_name(account_shortname) # look for existing psp psp = lookup_payment_provider(account.id) # psp does not exist -> create if psp is None: psp_info = create_payment_provider_information(account.id, psp_name, psp_data) # psp exists -> update else: psp_info = psp.get_provider_info() # update it print psp_name if psp_name is not None: psp_info.provider_type = psp_name if psp_data is not None: # validate if all mandatory fields are available validate_payment_provider_information(psp_info, psp_data) for key, new_value in psp_data.iteritems(): if new_value is None: continue else: psp_info.provider_info[key] = new_value return psp_to_dict(psp_info)
def account_client_keys(client_id, account_short): """ Returns a list of all key/secrets connected to the account """ account = lookup_account_by_name(account_short) if account.is_active(): return [dict(key=account.client.key, secret=account.client.secret)] else: raise AccountError("The account is not active.")
def from_account(client_id, account_name=None): """ Returns a list of venues connected to the account""" if client_id is not None: account = lookup_account_for_client(client_id) elif account_name is not None: account = lookup_account_by_name(account_name) return map(venue_to_dict, list_venues(account))
def account_info(oauth_client_id, account_id=None, account_shortname=None): """ Entrypoint for viewing account information. If the account_id contains None, it will return the info of the account attached to the oauth client. Args: oauth_client_id Id of the OAuth2 client asking for the information. account_id The id of the account to return Returns: A dictionary containing the information of the account including its identifier. { "id": 42, "name": "Tickee", "email": "*****@*****.**" } """ if account_id is not None: account = lookup_account_by_id(account_id) elif account_shortname is not None: account = lookup_account_by_name(account_shortname) else: account = lookup_account_for_client(oauth_client_id) if account.is_active(): return account_to_dict(account, include_theme=True, include_social=True) else: return AccountNotFoundError()
def visitors_of_account(account_short): """ Returns a list of users who have attended the events of an account """ account = lookup_account_by_name(account_short) users = Session.query(User).join(Ticket, TicketOrder, Order, Account)\ .filter(Account.id == account.id)\ .distinct(User.id).all() return map(user_to_dict, users)
def psp_details(client_id, account_shortname): """Returns detailed information about the psp""" account = lookup_account_by_name(account_shortname) psp = lookup_payment_provider(account.id) if psp is not None: return psp_to_dict(psp.payment_provider_info) else: raise PaymentError('Account has no payment provider set up.')
def account_detailed_statistics(client_id=None, account_id=None, max_months_ago=12): """Returns statistics per month""" account = lookup_account_by_name(account_id) if client_id is not None: require_account_owner(client_id, account) return detailed_ticket_count(account, max_months_ago)
def receive_notification(subscription_ref): """Receives a Saasy notification and queries the api for the subscription details. When it is a brand new subscription, the only way to link it to an account is via its referrer. When the subscription reference is linked, it will also be possible to find the correct account via its subscription reference. """ subscription_details = fetch_subscription_details(subscription_ref) # find internal subscription matching the reference try: subscription = lookup_subscription_by_reference(subscription_ref) except SubscriptionError: # find account matching referrer try: shortname = subscription_details.find('referrer').text account = lookup_account_by_name(shortname) # no match found, panic! except: tlogger.exception("Could not find any account associated with subscription %s"\ % subscription_ref) raise SubscriptionError( 'Could not associate saasy subscription to an account.') else: subscription = account.subscription subscription.subscription_reference = subscription_ref # link it to saasy subscription status = subscription_details.find('status').text # subscription is active if status == "active": product_name = subscription_details.find('productName').text customer_url = subscription_details.find('customerUrl').text plan = SAASY_SUBSCRIPTION_MAPPING.get(product_name) # fail if no plan matching the saasy product found if plan is None: tlogger.error( 'received subscription (ref %s) with unknown saasy product %s' % (subscription_ref, product_name)) raise SubscriptionError( 'Unknown product in saasy subscription found.') # update subscription subscription.subscription_type = plan.internal subscription.meta['customer_url'] = customer_url return dict() # subscription has inactive status -> revert to freemium elif status == "inactive": subscription.subscription_type = FreeSubscriptionPlan.internal subscription.meta['customer_url'] = None # unknown status else: tlogger.error("unknown subscription status '%s' for ref %s" % (status, subscription_ref))
def account_statistics(client_id=None, account_id=None): """Returns general account statistics""" account = lookup_account_by_name(account_id) if client_id is not None: require_account_owner(client_id, account) transaction_stats = get_or_create_transaction_statistic(account) transactions_allowed = account.subscription.get_feature( 'transactions_per_month') or -1 return dict(total_sold=total_tickets(account), transactions_this_month=transaction_stats.amount, transactions_allowed=transactions_allowed)
def order_new(client_id, user_id, tickettype_id, amount, account_short=None, as_guest=False, as_paper=False): """ Starts a new order session or retrieves one that was still active. Args: client_id user_id: Id of the user to start a session for. """ timeout_sessions(600) # assert permission to order tickettype if client_id is not None: require_tickettype_owner(client_id, tickettype_id) # get account to create order for. if account_short is not None: account = lookup_account_by_name(account_short) else: account = lookup_account_for_client(client_id) # start an order or get current one. if user_id is not None: user = lookup_user_by_id(user_id) order = start_order(user, account) else: order = start_order(None, account) # set order as guest (optional) if as_guest: order.meta['gifted'] = True # set order as paper ticket (optional) if as_paper: order.meta['paper'] = True add_tickets(order, tickettype_id, amount) # build successful order order_info = order_to_dict(order) return order_info
def account_exists(account_name, include_inactive=False): """ Entrypoint for checking if an account already exists with a particular account_name. Args: account_name: The name of the account that should be checked. Returns: If an account exists with the passed account_name, it will return: {'exists': True} The value will be False if it does not exist. """ account = lookup_account_by_name(account_name) if include_inactive or account.is_active(): return account_to_dict2(account) else: return False
def event_list(client_id=None, account_id=None, account_shortname=None, after_date=None, before_date=None, limit=50, past=False, active_only=True, public_only=True): """ Entrypoint for finding events matching specific filters. Args: account_id|account_shortname Only events owned by this account after_date Only events that start after this date will be returned before_date Only events that start before this date will be returned limit Only return at most this number of events. Defaults to 10. past Show events that occurred in the past. Defaults to True. """ if account_id is not None: account = lookup_account_by_id(account_id) elif account_shortname is not None: account = lookup_account_by_name(account_shortname) try: account_id = account.id except: account_id = None if client_id is not None: own_account = lookup_account_for_client(client_id) if not own_account == account: active_only = True # force active_only when not querying own account event_list = find_events(account_id_filter=account_id, after_date_filter=after_date, before_date_filter=before_date, limit=limit, past=past, active_only=active_only, public_only=public_only) return map(event_to_dict2, event_list)
def account_update(account_identifier, account_info): """ Replaces a account's data with the information located in account_info """ print account_info try: account = lookup_account_by_name(account_identifier) except: account = lookup_account_by_id(int(account_identifier)) for (key, value) in account_info.iteritems(): if value is None: continue # skip unset fields if key == "name": account.full_name = value elif key == "email": account.email = value elif key == "url": account.website = value.replace('https://', '').replace('http://', '') elif key == "vat": account.vat_percentage = value elif key == "subtitle": account.meta['subtitle'] = value elif key == "handling_fee": account.set_handling_fee(value) elif key == "currency": account.set_currency(value) elif key == "theme": account.meta['theme'] = value elif key == "phone": account.meta['phone'] = value elif key == "vatnumber": account.meta['vatnumber'] = value elif key == "social": account.meta['social'] = value elif key == "ext": account.meta['ext'] = value else: tlogger.error( 'received unknown information when updating account %s: %s' % (account_identifier, key)) return account_to_dict(account, True, True)
def venue_create(client_id, location_info, address_info=None, account_name=None): """ Handles the creation of a ``Venue`` and its ``Address`` and returns the result. Arguments: client_id: Name of the OAuth2Client that requested the application. location_info: Dictionary containing location information: - name address_info (optional): Dictionary containing address information: - street_line1, street_line2, postal_code, city, country account_name (optional): shortname of account that created the location """ # create venue if client_id is not None: account = lookup_account_for_client(client_id) elif account_name is not None: account = lookup_account_by_name(account_name) else: raise ex.VenueError('an account has to be linked to the location') venue = create_venue(location_info.get('name')) venue.created_by = account.id # create address if available if isinstance(address_info, dict): address = create_address(street_line1=address_info.get('street_line1'), street_line2=address_info.get('street_line2'), postal_code=address_info.get('postal_code'), city=address_info.get('city'), country_code=address_info.get('country')) venue.address = address return venue_to_dict(venue, include_address=True)
def account_deactivate(account_name): """ Deactivates the account """ account = lookup_account_by_name(account_name) account.is_active = False return account_to_dict(account)
def event_create(client_id, account_short, event_info, eventparts=[]): """ Entrypoint for creating an event and returning its information back as a dictionary. Args: client_id The id of the oauth_client who will organize the event. The event will be created for the account owning this client. account_short event_info eventparts """ account = lookup_account_by_name(account_short) if client_id is not None: require_account_owner(client_id, account) event = start_event(account.id, event_info.get('name') or EVENT_NAME) # create default eventpart if len(eventparts) == 0: add_eventpart(event.id, name=event.name) # add eventparts as described else: for eventpart in eventparts: if eventpart.get('starts_on') is not None: starts_on = datetime.datetime.fromtimestamp(eventpart.get('starts_on')) else: starts_on = defaults.EVENTPART_START minutes = eventpart.get('minutes') if starts_on is not None and minutes is not None: ends_on = None #starts_on + datetime.timedelta(minutes=minutes) else: ends_on = None add_eventpart(event_id=event.id, name=eventpart.get('name'), start_datetime=starts_on, end_datetime=ends_on, venue_id=eventpart.get('venue')) # create ticket types tickettypes = event_info.get('tickettypes') or [] for tickettype_info in tickettypes: # convert sales_end from ts to datetime if tickettype_info.get('sales_end') is not None: tickettype_info['sales_end'] = datetime.datetime.utcfromtimestamp(tickettype_info.get('sales_end')) # create ticket type tt = create_tickettype(price=tickettype_info.get('price') or TICKETTYPE_PRICE, units=tickettype_info.get('units') or TICKETTYPE_AMOUNT, currency=tickettype_info.get('currency') or "EUR", name=tickettype_info.get('name'), sales_end=tickettype_info.get('sales_end')) # link it to the event link_tickettype_to_event(tt, event) return event_to_dict2(event, short=False)