tessitura
v0.1.78
Published
### Overview
Downloads
1
Readme
NGS Tessitura App
Overview
This is a stand-alone NGS app that encompasses the
The set of repositories associated with Tessitura can be found here
Development
Prerequisites
Python 3.6.
Recommended to use conda, which is a package management system that simplifies running multiple versions of Python with different sets of requirements.
brew install miniconda # install
conda create --name tessitura python=3.6 # create a python environment
conda activate tessitura # activate it
Postgres/Redis
Postgres and Redis are launched in docker.
# Build Image
docker-compose build
# Run Images
docker-compose up
Natgeo NPM / Pypi access.
See these documents on confluence for getting access to the npm and pypi registries.
Getting Started
Clone repository
git clone [email protected]:nationalgeographicsociety/Digital/tessitura/tessitura.git
cd tessitura
Configure Environment
Copy the .env.example file and rename it .env.
Edit .env
to fill in values for secret params (marked at the top of the file). You can get those secret values from another developer, or from vault if you have access.
Note that the .env
file will get loaded on django startup (from base.py), so no need to source the file.
Install packages
pip install -r requirements.txt # make sure that you have virtual environment activated
npm install # install modules for ticketing app
npm --prefix apps/frontend/ install # install modules for the React app
npm --prefix apps/frontend/ run build
Collect static
./manage.py collectstatic
Update database schema
./manage.py migrate --settings tessitura.settings.development
Run server
./manage.py runserver --settings tessitura.settings.development
Note: If you have issues with loading static files check if you have DEBUG set on true or try running server like this:
manage.py runserver --insecure --settings tessitura.settings.development
Run Tests
To run integration tests, run the following from the project root:
# Run all tests
./manage.py test --settings tessitura.settings.integration
# Run tests from one file
./manage.py test tests.test_donation --settings tessitura.settings.integration
# Run tests from single TestCase
./manage.py test tests.test_donation.TestDonation --settings tessitura.settings.integration
See https://docs.djangoproject.com/en/2.2/topics/testing/overview/#running-tests
API App
The API app is essentially the gateway between the code in ngs-tessitura and the Tessitura API. Most of the python files within the API app contain the Classes which interact directly with the Tessitura API Endpoints. There should not be any other places in the code outside of this app which call the Tessitura API directly, instead they should reference the Classes and Methods within this app. The urls and views within the api app act as the gateway between Mercator and these classes which interact with Tessitura's API. So, for example, if a user adds a performance to their cart from Mercator, Mercator sends a request to a url within the api app, which routes to a view within the api app, which will then use one or more of the Class Methods within the api app to access Tessitura API Endpoints and add the performance to the cart.
API Classes
cart.py
- Description:
- Contains the
Cart
class which provides access to all of Tessitura's Cart API Endtpoints.
- Contains the
- Methods/Uses:
- Add/Remove performances, gift certificates.
- Add/Remove a donation to NGS.
- Apply a promo codes to get a discount on performances in the cart.
- Apply a gift certificate to a cart as payment towards the order total.
- Clear out a cart which removes all cart items and destroys the cart.
- Get a cart and all of its properties, contents, and costs.
- Get an order (which is the receipt of a cart that has been paid), and all properties, contents, costs, payments and total balance.
- Validate, process the payment, and save an order for everything in the cart.
- Description:
constituent.py
- Description:
- Contains the
Constituent
class which provides access to the "constituent" endpoints in Tessitura which is the same as a "user" in Mercator.
- Contains the
- Methods/Uses:
- Add/Update a Constituent and all of their associated data like addresses, email, phone number, interests, etc...
- Get a constituent and all of their associated data.
- Description:
order.py
- Description:
- Contains the
Order
class which provides access all "order" related Tessitura Endpoints. - An "order" is like a receipt that generated when payment is processed for a cart. It contains all of the information that was in the cart, in addition to payment information.
- Contains the
- Methods/Uses:
- Generates an email sent to the user that summarizes the order and the payment.
- Description:
performance.py
- Description:
- Contains the
Performance
class which provides access to all "performance" endpoints in Tessitura which is very simlar to an "event" in Mercator. - The difference between Tessitura Performances and Mercator Events is that a Tessitura performance occurs at one particular day and time, so a recurring Mercator Event will have many corresponding Tessitura Performances, which are grouped within a Tessitura Production Season. In that case, the Event is linked up to that Production Season. Whereas, when a Mercator Event occurs at one day and time only, that Event would be linked directly up to a Tessitura Performance.
- Contains the
- Methods/Uses:
- Gets data for a given performance including the dates, show times, ticket types, pricing info, etc...
- Gets production seasons for performances and gets performances for production seasons.
- Description:
referencedata.py
- Description:
- Contains the
ReferenceData
class which provides access to all of the "reference data" endpoints in Tessitura that are referenced fromPerformance
,Cart
, andConstituent
.
- Contains the
- Methods/Uses:
- Get the list of available types for objects within Tessitura, like the list of available countries, states and modes of sale.
- Description:
registration.py
- Description:
- Contains the
Registration
class which provides access to all
- Contains the
- Description:
transaction.py
- Methods/Uses:
- Gets a list of accepted payment types and accepted credit card types.
- Methods/Uses:
websession.py
- Description:
- Contains the
Websession
class which provides access to all Tessitura endpoints that we need to create and maintain sessions and logins. - There is a one-to-one relationship between a Websession and a Cart. When a Websession is created, that generates a session and a session key which is the identifier used to get a particular cart or websession.
- Contains the
- Methods/Uses:
- Create a websession, which in turn, creates a cart.
- Login a user either as a guest or by email, and associate that logged in user with that websession.
- Description:
Additional API Methods
helpers.py
- Description:
- A collection of methods not associated with any particular class, but are wrappers for class methods which perform reusable functionality on the data returned by those class methods or reformats the data that is passed to those methods.
- Methods/Uses:
- Look up countries or states
- Combine the get and the create methods for websessions to do a get_or_create
- Update user interests
- Description:
utils.py
- Description:
- A collection of methods which are used by the API Classes or Views.
- Methods/Uses
- get_event_image_and_name() - Hits an api endpoint in Mercator which returns info about the event like it's title and key image.
- process_cart_data() - Formats cart data into a pythonic dictionary in the format that is convenient for the API Views.
- rest_call() - A base method that wraps around every single API call we make to Tessitura and handles all the boiler plate repeatable logic that we want to do for every API call.
- Description:
NOTES:
- Although the methods that are in these two files, helpers.py and utils.py, are similar as far as what they do, they should remain in separate files to avoid causing a cyclic import issue.
tickets app
The tickets app contains the urls, views, and templates for the 3 main pages that guides the user through the cart checkout process. When a cart is created it has a ts_session_key which gets generated when the web session is created, and acts as the unique identifier for the cart within Tessitura. Just about every method that does anything with a cart needs this value, and also looks at the cart's Time To Live (TTL) value to make sure that the cart has not timed out. (Carts have a 20 minute timeout). The cart also contains an "Id" field, which is an integer value that will end up being used to uniquely identify the Order that gets generated when a cart is processed for payment.
Review Cart Displays all items in the cart and provides a final opportunity to make changes to the cart before proceeding to make a payment. The user can remove items from the cart, they can add a donation to the cart, as well as apply a promo code for a discount or apply a gift certificate as a payment. They can also return to Mercator to continue shopping and add more items to their cart. Once the user is done w/ their cart they click the checkout button to proceed to the Checkout page.
Checkout Cart & Process Payment Displays a form for the user to fill in all information required to make a credit card payment and shows the summation of costs/payments and total balance and passes that form data to our processing view to process the payment. Once the payment processes, the card is charged and an Order is created in Tessitura's system, and the user gets redirected to the Order Summary page.
Order Summary Displays a "receipt" of what was in the cart based on the Order record in Tessitura, this page shows subtotals, fees, total due, total paid, etc... There is no functonality on this page, it is a summary of what happened.
- NOTES:
- There are a ton of methods in tickets/utils.py which are used by the views to perform frequently needed functions like formatting data, or wrapping around some api class methods in reusable ways.
users app
The users app stores data about carts that were created, and the corresponding orders that were generated when those carts were processed for payment. There are two ways to checkout a cart, either as a guest or as a user authenticated through SSO. SSOUser and UserOrder tables store the data we need to know which user in ngs-tessitura had a cart and order and also link that ngs-tessitra user to the Tessitura system's Constituent record and NGS' People API users. GuestUser stores data for the guest user case.
- Models
- SSOUser - An instance of a user in this app being linked to a Constituent in Tessitura and possibly to user record in the People API.
- user - The django user in the ngs-tessitura project.
- tessitura_id - The ConstituentId in Tessitura's API that is associated with this user.
- ngs_uid - The unqiue identifier in the People API that is associated with this user. to know about the member benefits. Since the CMS has not fully implement SSO, we use NGS Tessitura app for authenticating the user and then creating and passing the member token to the CMS. The CMS can then query the NGS Tessitura about the user and the benefits they are eligable for
- member_type - There are 3 types of users: Member, Staff and Regular. The NGS Tessitura app store this info on the SSOUser model so that it can pass this to CMS as and when needed. The set_cms_member_cookies methods in NGS Tessitura gets the member token after successful authentication, sets a member token cookie in NGS Tessitura app domain and passes the member token to CMS (session_processor). The session_processor view in the cms then get the member token from the url params and sets it as a cookie in the CMS.
- UserOrder - An instance of a cart that was processed for payment, and the corresponding order that was made by an user authenticated by SSO.
- sso_user - FK to the SSOUser model.
- order_id - The id number that uniquely identifies an order (cart that has been processed for payment) in Tessitura's system.
- ts_session_key - The unique identifier of the cart/session in Tessitura's system.
- GuestUser - An instance of a cart that was processed for payment, and the corresponding order that was made by a "guest" user. Meaning, they did not authenticate, and chose to checkout their cart as a guest.
- tessitura_id - The ConstituentId in Tessitura's API that is associated with this user.
- order_id - The id number that uniquely identifies an order (cart that has been processed for payment) in Tessitura's system.
- ts_session_key - The unique identifier of the cart in Tessitura's system.
- SSOUser - An instance of a user in this app being linked to a Constituent in Tessitura and possibly to user record in the People API.
websessions app
The websessions app can be thought of as a bridge between the Mercator session and the Tessitura session so that as the user goes back and forth between the two Applications we can maintain the state of the user, including the shopping cart.
- Model
- TessituraSession - An instance of a Tessitura Session for a particular user, serves as a link between the Mercator session and the Tessitura session, and stores the time the session was acrtivated in Tessitura which is used to calculate the amount of remaining time in a Tessitura session and whether or not that session is active.
- user - The unique identifier that links this record to the user in Mercator. Unauthenticated Mercator users pass their session key to Tessitura as the 'mercator_user' field and that gets stored in this model's "user" field. Authenticated Mercator users pass their username, which is enforced unique in Mercator.
- session_key - The unique identifier of the cart/session in Tessitura's system.
- TessituraSession - An instance of a Tessitura Session for a particular user, serves as a link between the Mercator session and the Tessitura session, and stores the time the session was acrtivated in Tessitura which is used to calculate the amount of remaining time in a Tessitura session and whether or not that session is active.
tessitura
Contains the settings files, app configs, and the primary urls file for the ngs-tessitura app.
Assets
Contains all of the CSS, JS, and image files. The files in here get copied into the tessitura/staticassets folder by collectstatic.
React/frontend
The apps/frontend folder contains all of the React Components. In order to develop the React Components you will need to run the webpack server in dev mode.
cd to apps/frontend
npm install
npm run dev
This server will watch your js files (apps/frontend/src/components) for changes and live re-compile
Creating New Top-Level React Components
- views.py for desired app, add the following view (changing name and template as needed):
def index(request):
context = {
'order_history': '',
}
template = loader.get_template('users/order_history_fe.html')
return HttpResponse(template.render(context, request))
- urls.py for desired app, add the following line (changing route, view variable and name):
url(r'^order/$', index, name='index'),
- urls.py import the view at the top:
from .views import order_history, order_history_api, index
- create html file in templates/foldername/filename_fe.html - use /templates/cart/cart_fe.html as reference
- change the
id=""
portion of the _fe.html template (this is how we wire up the REact Component to this django Template) - Create new component in apps/frontend/src/components, use other components as reference
- Make sure the container matches the id you set in the _fe.html template:
const container = document.getElementById("cart");
- Add the new Component to apps/frontend/src/index.js
import Cart from "./components/Cart/Cart";
- Stop and start the webpack server
npm run dev
to pickup your new component!
Config & App Setup
Create a superuser ./manage.py createsuperuser
Log in to Admin as superuser in browser. /tickets/admin/
Create an API Auth Token /tickets/admin/rest_framework_api_key/apikey/
Add that token to the local_settings file in your mercator project. HAPPENINGS_SETTINGS['GANGSTA_API_AUTHTOKEN'] = 'm9rau1Wm.8TAAXx9ylPJzJwFoftIYE7BT182KGI80'
Link a Mercator Event to a Performance in Tessitura. For single-date events, find the performance_id of the Tessitura Performance and enter that into the Mercator Event's tessitura_performance_id field. For multi-date events, find the production_season_id of the Tessitura Performances' Production Season, and enter that into the Event's tessitura_performance_id field. Save & Publish that Event, and you should now see a Ticket Selector on the event's detail page and be able to select tickets and add them to a cart, review your order, checkout your order and finally view a summary of your order.
Deploy
Contains deployment scripts and environment files for develop, staging and production ngs-tessitura boxes.
Make sure to use our standard release management tool for creating a new release tag and changelog. Use the --dry-run
option to check that the new release will have the right tag version and changelog
npx standard-version [--release-as patch|minor|major ] [--dry-run]
Templates
Contains all of the templates needed to display the Review Page, Checkout Page, and Order Summary Page.
Requirements
List of pip packages needed to run ngs-tessitura. To update run: pip install -r requirements