custom 501 pre so

Upload: alextoader

Post on 09-Oct-2015

43 views

Category:

Documents


3 download

DESCRIPTION

Custom 501 Pre So

TRANSCRIPT

  • 5/19/2018 Custom 501 Pre So

    1/88

    PowerSchool University2014

    Customizations 501:PowerSchool Customizations Academy

    Trainer Name

    Trainer/Consultant

  • 5/19/2018 Custom 501 Pre So

    2/88

    Warning

    PowerSchool Academy is intended for advanced PowerSchool

    users with solid customization skills including HTML, CSS, and

    JavaScript (jQuery). The pace of the class will also be faster than

    other customization courses.

    If you are not comfortable with any of these topics, and you havenot taken the self assessment, please take a few minutes to take

    the self assessment to make sure you are ready for this course.

    You may take the self assessment here:

    2

  • 5/19/2018 Custom 501 Pre So

    3/88

    Objectives

    Learn how to plan large projects that involve many tables andcustom screens to avoid pitfalls

    Learn how to create advanced database extensions with one-

    to-one, one-to-many, and standalone tables Learn how to use tlist_child and tlist_standalone to create a

    user interface for adding, deleting, and modifying records

    See how page fragments can improve scalability and reusability

    of customizations Use jQuery to insert data into pages

    Create a plugin to take home

    3

  • 5/19/2018 Custom 501 Pre So

    4/88

    Custom Fields - ALittle History

    4

  • 5/19/2018 Custom 501 Pre So

    5/88

    Is harder to access

    Cannot be obtained through direct SQL

    Impacts performance

    Legacy Custom Fields

    5

    Legacy Custom fields are created inside a Character Large Object(CLOB). When data is stored this way, it:

    Datatypes not defined

    One-to-many records not supported

    In addition, legacy custom fields had other issues:

  • 5/19/2018 Custom 501 Pre So

    6/88

    Database Extensions Benefits

    6

    Supports one-to-one, one-to-many. and standalone tables Allows fields to have defined datatypes

    Can be based on most existing tables

    Allows direct access to tables and fields from SQL

    Improves performance

    Includes enhanced customization features

  • 5/19/2018 Custom 501 Pre So

    7/88

    DatabaseExtensions

    7

  • 5/19/2018 Custom 501 Pre So

    8/88

    Types of Database Extensions

    8

  • 5/19/2018 Custom 501 Pre So

    9/88

    One-to-One Table Extensions

    Can only have a single one-to-one table per extension group Must have a maximum of one record in the child table for each

    record in the parent table

    Are most similar to legacy custom fields

    9

  • 5/19/2018 Custom 501 Pre So

    10/88

    One-to-One Field

    10

    Students

    dcidstudent_numberLast_nameFirst_name

    Students_Demographics

    studentsdcidShoe Size

    Shirt SizeBackpack Color

    Students_ID_Numbers

    studentsdcidDistrict ID

    Library Card NumberSelective Ser vice Number

    Room

    dcidroom_numberNameDepartment

    Room_Equipment

    roomdcidDesks

    ScreenProjector

  • 5/19/2018 Custom 501 Pre So

    11/88

    One-to-Many Table Extensions

    Can have multiple one-to-many tables per extension group Each child table can have zero or more records for each record

    in the parent table

    Similar to tables such as Stored_Grades, CC,

    Special_Programs, Sections

    11

  • 5/19/2018 Custom 501 Pre So

    12/88

    One-to-Many Table (Child)

    For a given child table, one row in the parent table is related tozero or more rows in the child table

    Similar tables Stored_Grades, CC, Special_Programs, Sections

    12

    Students

    dcid

    student_numberLast_nameFirst_name

    AthleticAwards

    studentsdcid

    Award_NameDate_Given

    AcademicAwards

    studentsdcid

    Award_NameDate_Given

    AthleticTeams

    studentsdcidTeamYear

    AcademicTeams

    studentsdcidTeamYear

    Courses

    dcid

    Course_numberCourse_nameCredit_Hours

    Courses_Textbooks

    coursesdcid

    TitleAuthorPublisherCopyrightVersion

  • 5/19/2018 Custom 501 Pre So

    13/88

    Standalone Table Extensions

    Can have multiple standalone tables per extension group No database level relation to any other table

    Asset Management, Values for fields in other tables

    13

  • 5/19/2018 Custom 501 Pre So

    14/88

    Standalone Table (Independent)

    No database-level relationship to any PowerSchool table Useful for tracking assets

    Useful for creating user-manageable lists

    14

    Laptops

    dcidID_TagBrandModelSerial_NumberOSRAMHDD

    LaptopOS

    dcidNameCompanyVersion

    Textbooks

    dcidTitleAuthorPublisherCopyrightVersion

  • 5/19/2018 Custom 501 Pre So

    15/88

    Standalone Table (Independent)

    15

    Laptops

    dcidID_TagBrandModelSerial_NumberOSRAMHDD

    LaptopOS

    dcidNameCompanyVersion

    Courses

    dcidCourse_numberCourse_nameCredit_Hours

    Textbooks

    dcidTitleAuthorPublisherCopyrightVersion

    Courses_Textbooks

    coursesdcidtextbooksdc id

    Students

    dcidstudent_numberLast_nameFirst_name

    Students_Laptops

    studentsdcidLaptopsdcid

    No database-level relationship to any PowerSchool table Useful for tracking assets

    Useful for creating user-manageable lists

  • 5/19/2018 Custom 501 Pre So

    16/88

    Extension Groups

    Groups are structural One-to-one table must be first table created

    There can be only a single one-to-one table in any group

    Many one-to-many and standalone tables are allowed

    16

  • 5/19/2018 Custom 501 Pre So

    17/88

    Grouping Tables into Extension Groups

    Determine what makes logical sense for the circumstance

    17

    Athletics AcademicsStudents

    dcidstudent_numberLast_name

    First_name

    AthleticAwards

    studentsdcidAward_NameDate_Given

    AcademicAwards

    studentsdcidAward_NameDate_Given

    AthleticTeams

    studentsdcidTeamYear

    AcademicTeams

    studentsdcidTeamYear

  • 5/19/2018 Custom 501 Pre So

    18/88

    Grouping Tables into Extension Groups

    Determine what makes logical sense for the circumstance

    18

    Awards

    Teams

    AthleticAwards

    studentsdcidAward_NameDate_Given

    AcademicAwards

    studentsdcidAward_NameDate_Given

    AthleticTeams

    studentsdcidTeamYear

    AcademicTeams

    studentsdcidTeamYear

    Students

    dcidstudent_numberLast_name

    First_name

  • 5/19/2018 Custom 501 Pre So

    19/88

    Grouping Tables into Extension Groups

    Determine what makes logical sense for the circumstance

    19

    Extra-curricular

    Students_Demographics

    studentsdcidShoe SizeShirt SizeBackpack Color

    AthleticAwards

    studentsdcidAward_NameDate_Given

    AcademicAwards

    studentsdcidAward_NameDate_Given

    AthleticTeams

    studentsdcidTeamYear

    AcademicTeams

    studentsdcidTeamYear

    Students

    dcidstudent_numberLast_name

    First_name

  • 5/19/2018 Custom 501 Pre So

    20/88

    Datatypes

    String Integer

    Date

    Double

    Boolean

    CLOB (Character Large Object)

    BLOB (Binary Large Object)

    20

  • 5/19/2018 Custom 501 Pre So

    21/88

    A Small, HealthyDose of Database

    Design Concepts

    21

  • 5/19/2018 Custom 501 Pre So

    22/88

    Database Design

    22

    Build It Right!

  • 5/19/2018 Custom 501 Pre So

    23/88

    Basic Design Concepts

    23

    Start on paper Create a naming standard

    Create on a test server

    Test, test, test

    Only install when correct

    Cant delete, so get it right

  • 5/19/2018 Custom 501 Pre So

    24/88

    Basic Design Concepts

    Dont duplicate data, link to it Standalone tables = consistent data

    Read a database design book

    24

  • 5/19/2018 Custom 501 Pre So

    25/88

    Using DatabaseExtensions in

    Page Customization

    25

  • 5/19/2018 Custom 501 Pre So

    26/88

    Similar to including core fields or legacy custom fields Minor Difference the table designation

    - No more table numbers

    - Use PrimaryTable.ExtensionGroupName

    [PrimaryTable.ExtensionGroupName]Field_Name

    Including One-to-One fields in Custom Pages

    26

  • 5/19/2018 Custom 501 Pre So

    27/88

    A brand new function: tlist_child Will auto-generate an HTML table to display rows of records

    from the designated child table

    Includes an Add button and Delete buttons for each row that

    has been created

    ~[tlist_child:

    ..;

    displaycols:;

    fieldNames:;type:]

    Including One-To-Many Tables in Custom Pages

    27

  • 5/19/2018 Custom 501 Pre So

    28/88

    A brand new function: tlist_standalone Will auto-generate an HTML table to display rows of records

    from the designated independent table

    Includes an Add button and Delete buttons for each row that

    has been created

    ~[tlist_standalone:

    .;

    displaycols:;

    fieldNames:;type:]

    Including Standalone Tables in Custom Pages

    28

  • 5/19/2018 Custom 501 Pre So

    29/88

    Improving the Usabilityof Tlist_child and

    Tlist_standalone

    29

  • 5/19/2018 Custom 501 Pre So

    30/88

    Improving the Usability of Tlist_child andTlist_standalone

    Date fields PS Date Picker

    Boolean fields check box

    All others input boxes, approximately 20 characters wide

    Other input types can be defined

    Needs a JavaScript file and some basic scripting

    30

  • 5/19/2018 Custom 501 Pre So

    31/88

    Menu

    Insert JavaScript call in head~[wc:commonscripts]

    Directly after the tlist_ function, add a script that defines the

    options, and then links the list of options to a specific field

    var ValName = [];

    ValName.push(['','Select a Value']);

    ValName.push(['Value 1','Label 1']);

    ValName.push(['Value 2','Label 2']);

    tlistText2DropDown('Field_Name',ValName);

    31

  • 5/19/2018 Custom 501 Pre So

    32/88

    Radio Buttons

    Insert JavaScript call in head~[wc:commonscripts]

    Directly after the tlist_ function, add a script that defines the

    options, and then links the list of options to a specific field

    var ValName = {};

    ValName.push(['F','Female']);

    ValName.push(['M','Male']);

    tlistText2RadioButton('Field_Name',ValName);

    32

  • 5/19/2018 Custom 501 Pre So

    33/88

    Text Area

    Insert JavaScript call in head~[wc:commonscripts]

    Directly after the tlist_ function, add a script that defines the

    options, and then links the list of options to a specific field

    tlistText2TextArea('Field_Name',Rows,Columns);

    33

  • 5/19/2018 Custom 501 Pre So

    34/88

    Static/Read-Only Text

    Insert JavaScript call in head~[wc:commonscripts]

    Directly after the tlist_ function, add a script that defines the

    options, and then links the list of options to a specific field

    tlistText2StaticText('Field_Name');

    34

  • 5/19/2018 Custom 501 Pre So

    35/88

    Multiple Formats in One Table

    Multiple formats in one script Must have unique variable names

    var ValName1 = [];

    ValName1.push(['','Select a Value']);ValName1.push(['Value 1','Label 1']);

    ValName1.push(['Value 2','Label 2']);

    tlistText2DropDown('Field_Name',ValName1);

    var ValName2 = {};

    ValName2.push(['F','Female']);

    ValName2.push(['M','Male']);

    tlistText2RadioButton('Field_Name',ValName2);

    tlistText2TextArea('Field_Name3',Rows,Columns);

    35

  • 5/19/2018 Custom 501 Pre So

    36/88

    Creating Values for a Drop-down Menu

    Use tlist_sql to create menu values

    Query any table Stock, Standalone, etc.

    Stock tables made just for this: States, CountryISOCodeLU,

    LanguageISOCodeLU

    var StateValues = [];

    StateValues.push(['','Select a Value']);

    ~[tlist_sql;

    SELECT state

    FROM states

    WHERE country = USA'ORDER BY state]

    StateValues.push([~(state),~(state)]);

    [/tlist_sql]

    tlistText2DropDown('State',StateValues);

    36

  • 5/19/2018 Custom 501 Pre So

    37/88

    Adjusting Widths of Input Boxes

    CSS is the key Each input box has a class equal to its field name

    In HTML, input box size can be controlled with size=

    In CSS, use width and define it in pixels (px)

    .Zip {width:55px;}

    .Phone {width:140px;}

    .StartDate {width:90px;}

    .EndDate {width:90px;}

    37

  • 5/19/2018 Custom 501 Pre So

    38/88

    Insertion Points

    38

  • 5/19/2018 Custom 501 Pre So

    39/88

    Insertion Points and Page Fragments

    Used to customize existing pages in PowerSchool

    Code is kept in separate file from page being customized

    New code is inserted into existing page

    Multiple insertion points exist

    PowerSchool still allows for page customization, insertion

    points are just another option

    39

  • 5/19/2018 Custom 501 Pre So

    40/88

    Insertion Points and Page Fragments

    40

    PowerSchool Page

    This is my page

    Some Information

    INSERTION POINT HERE

    Page Fragment

    This is some inserted code

    Insert

  • 5/19/2018 Custom 501 Pre So

    41/88

    Why Use Insertion Points

    The code is in a separate file and the page is not actually

    customized, page updates will be seen after upgrades

    They can be packaged into a plugin and easily installed on

    other servers

    Multiple insertion points can be used on a single page, allowing

    for separation of customizations

    41

  • 5/19/2018 Custom 501 Pre So

    42/88

    Insertion Points Where Are They

    admin_header_css.txt The standard admin portal header

    for unframed pages

    admin_header_frame_css.txt The standard admin portal

    header

    admin_footer_css.txtThe standard admin portal footer for

    unframed pages

    admin_footer_frame_css.txt The standard admin portalfooter

    42

  • 5/19/2018 Custom 501 Pre So

    43/88

    Insertion Points Where Are They

    teachers_nav_css.txt PowerTeacher portal left navigation

    frame

    guardian_footer_yui.txt The standard parent/student

    portal footer

    /admin/students/more2.html Admin portal left

    navigation frame for student pages

    /admin/faculty/more2.html Admin portal left navigationframe for staff pages

    43

  • 5/19/2018 Custom 501 Pre So

    44/88

    ~[cust.insertion_point:content.footer]

    ~[text:psx.txt.wildcards.admin_footer_css.legend]

    ~[text:psx.txt.wildcards.admin_footer_c

    ss.page_icons]

    ~[pluginnavlinks:admin.drawer]

    ~[wc:report_issue]

    ~[wc:legal_copyright]

    ~[wc:ux_analytics]

    admin_footer_css.txt

    44

  • 5/19/2018 Custom 501 Pre So

    45/88

    ~[cust.insertion_point:content.footer]

    ~[text:psx.txt.wildcards.admin_footer_css.legend]

    ~[text:psx.txt.wildcards.admin_footer_c

    ss.page_icons]

    ~[pluginnavlinks:admin.drawer]

    ~[wc:report_issue]

    ~[wc:legal_copyright]

    ~[wc:ux_analytics]

    admin_footer_css.txt

    45

    This will be referred toas content.footer

  • 5/19/2018 Custom 501 Pre So

    46/88

    Page Fragments

    Small snippets of code

    Not intended as a standalone page

    Code will be inserted into an existing PowerSchool page

    Filename determines where it will be inserted

    Generally mixed content (HTML, CSS, JavaScript)

    46

  • 5/19/2018 Custom 501 Pre So

    47/88

    Standard Insertion Points

    content.header Right below the School and Term selection

    content.footer Near the bottom of the page, above the

    copyright bar in the content area

    leftnav.footer Right below the left navigation but above any

    PowerSource or Mobile App content

    47

  • 5/19/2018 Custom 501 Pre So

    48/88

    Standard Insertion Points

    page.header The last line in the wildcard commonscripts.txt

    report.tabs After the last , before the in the

    report tabs

    student.alert After the ~[studentalert] tag in the file

    title_student_end_css.txt

    48

  • 5/19/2018 Custom 501 Pre So

    49/88

    Special Note

    On the Visual Scheduler and Seating Chart pages, the

    content.footer will be hidden and unsupported

    49

  • 5/19/2018 Custom 501 Pre So

    50/88

    Inserting a Page Fragment

    Page Fragments are inserted in the same fashion wildcards are

    inserted

    Filename of the page fragment will determine what file the

    fragment is inserted into as well as the location in the file

    Page fragments can be inserted into a page one of two ways:

    - URL based The fragment is inserted into a single page

    - Wildcard based The fragment will be rendered in every

    page the wildcard is used on

    50

  • 5/19/2018 Custom 501 Pre So

    51/88

    URL-Based Insertion

    51

    Add emergency phone numbers

  • 5/19/2018 Custom 501 Pre So

    52/88

    URL-Based Insertion

    52

    Add emergency phone numbers

    Whats New

    See whats new in the latest feature release of

    PowerSchool. Read more...

    Legend

    home.html rendered code

  • 5/19/2018 Custom 501 Pre So

    53/88

    URL-Based Insertion

    53

    Emergency Phone Number

    Police- 384-554-3876

    Fire - 384-554-2954

    Filename: home.emergPhone.content.footer.txt

  • 5/19/2018 Custom 501 Pre So

    54/88

    URL-Based Insertion

    54

    Page to apply fragment towith no .html

    home.Emergency_Numbers.content.footer.txt

    Fragment name

    Insertion point

  • 5/19/2018 Custom 501 Pre So

    55/88

    Now ItsYour Turn

    Complete hands-onactivity 1:

    Creating a PageFragment

    55

  • 5/19/2018 Custom 501 Pre So

    56/88

    Wildcard Page Fragments

    Inserted into a wildcard

    Included on all pages the wildcard is used on

    Must be in the wildcard folder

    Naming convention is the same

    56

  • 5/19/2018 Custom 501 Pre So

    57/88

    Wildcard-Based Insertion

    57

    Wildcard to apply fragmentto, with no .txt

    admin_footer_css.myInsert.content.footer.txt

    Fragment name

    Insertion point

  • 5/19/2018 Custom 501 Pre So

    58/88

    Now ItsYour Turn

    Complete hands-onactivity 2:

    Creating a WildcardPage Fragment

    58

  • 5/19/2018 Custom 501 Pre So

    59/88

    Creating Custom Insertion Points

    You can create a custom insertion point on any page

    It will function like built-in PowerSchool insertion points

    You must define a name for the insertion point to be used in the

    page fragment name

    Once you create an insertion point, the page will be customized

    59

  • 5/19/2018 Custom 501 Pre So

    60/88

    Creating Custom Insertion Points

    60

    Creates the insertionpoint

    ~[cust.insertion_point:POINTNAME;DEFAULT_CONTENT]

    Name used to reference

    the insertion point

    Default content(usually blank)

  • 5/19/2018 Custom 501 Pre So

    61/88

    Creating Custom Insertion Points

    61

    ~[text:psx.html.admin_students.generaldemographics.

    student_number]

    ~[x:insertfile;state/

    demographics~[displaypref:districtstate].html]

    ~[cust.insertion_point:table.end]

  • 5/19/2018 Custom 501 Pre So

    62/88

    URL-Based Insertion

    62

    generaldemographics.myInsert.table.end.txt

    This will insert the content into the insertion point that was

    created on the previous slide

  • 5/19/2018 Custom 501 Pre So

    63/88

    Now ItsYour Turn

    Complete hands-onactivity 3:

    Creating a CustomInsertion Point

    63

  • 5/19/2018 Custom 501 Pre So

    64/88

    jQuery Selectors

    64

  • 5/19/2018 Custom 501 Pre So

    65/88

    jQuery Selectors

    65

    What if the content footer is not where you want your

    new content?

  • 5/19/2018 Custom 501 Pre So

    66/88

    jQuery Selectors

    With jQuery, you can use not only IDs, but also CSS and element

    types to select objects in the DOM.

    66

    Here are some examples:

  • 5/19/2018 Custom 501 Pre So

    67/88

    jQuery Selectors

    With jQuery, you can use not only IDs, but also CSS and element

    types to select objects in the DOM.

    67

    Here are some examples:

  • 5/19/2018 Custom 501 Pre So

    68/88

    jQuery Selectors

    With jQuery methods, you can interact with the elements you

    have selected.

    68

    Here are some examples:

  • 5/19/2018 Custom 501 Pre So

    69/88

    jQuery Selectors

    69

  • 5/19/2018 Custom 501 Pre So

    70/88

    jQuery Selectors

    70

    Displays information about theobject you are inspecting.

  • 5/19/2018 Custom 501 Pre So

    71/88

    jQuery Selectors

    71

    http://api.jquery.com/category/selectors/

    http://api.jquery.com/category/selectors/
  • 5/19/2018 Custom 501 Pre So

    72/88

    jQuery Selectors

    72

    http://www.w3schools.com/jquery/jquery_ref_selectors.asp

    http://www.w3schools.com/jquery/jquery_ref_selectors.asp
  • 5/19/2018 Custom 501 Pre So

    73/88

    Quick Code

    73

    var myVal = $j('#fieldDOB').val();

    console.log(myVal);

    Use jQuery selectors to return the value of the DOB

    field from the un-framed Demographics page.

  • 5/19/2018 Custom 501 Pre So

    74/88

    Quick Code

    74

    var myVal=$j('#fieldDOB').parent().html();

    console.log(myVal);

    Use jQuery selectors to return the HTML of the

    tag that contains the DOB field from the unframedDemographics page.

  • 5/19/2018 Custom 501 Pre So

    75/88

    Quick Code

    75

    var myVal=$j('#fieldDOB').parent().prev('td').text();

    console.log(myVal);

    Use jQuery selectors to return the value of the title of

    the DOB field from the unframed Demographics page.

  • 5/19/2018 Custom 501 Pre So

    76/88

    Quick Code

    76

    $j('#fieldDOB').parent().prev('td').text('Date of Birth');

    Use jQuery selectors to change the title of the DOB

    field to Date of Birth on the unframed Demographicspage.

  • 5/19/2018 Custom 501 Pre So

    77/88

    Quick Code

    77

    Use jQuery selectors to add a new table row after DOB

    with a title and input for Country of Birth on theunframed Demographics page.

    var insertThis='Country of

    Birth

  • 5/19/2018 Custom 501 Pre So

    78/88

    Now ItsYour Turn

    Complete hands-onactivity 4:

    Appending a CustomInsertion Point

    78

    Creating and

  • 5/19/2018 Custom 501 Pre So

    79/88

    Creating andInstalling Plugins

    79

    S h l l

  • 5/19/2018 Custom 501 Pre So

    80/88

    PowerSchool Plugins

    Plugins are used to combine all necessary files into a single

    zipped file

    The zipped file also contains a plugin definition

    Plugins can be transferred to other servers very easily

    Plugins are first installed on the server Once installed, plugins can be enabled or disabled

    80

    C i Pl i

  • 5/19/2018 Custom 501 Pre So

    81/88

    Creating a Plugin/admin/customization/CreatePackagePage.action

    81

    A t bl Fil T

  • 5/19/2018 Custom 501 Pre So

    82/88

    Acceptable File Types

    Database extension definition

    XML files

    Custom pages

    Page fragments

    Page fragment meta files

    Image files (GIF, PNG, JPEG, JPG) or PDF files (PDF)

    CSS files

    JavaScript files

    Other web directory artifacts

    82

    I t lli Pl i

  • 5/19/2018 Custom 501 Pre So

    83/88

    Installing a Plugin

    83

    System > System Settings > Plugin Management Configuration

    I t t N t

  • 5/19/2018 Custom 501 Pre So

    84/88

    Important Notes

    If database extensions are included, the PowerSchool and

    ReportWorks services must be restarted for the extension(s) tobe created

    If any of the asset files already exist on the server, the install

    will fail (to avoid overwriting files)

    When a plugin is disabled, all custom pages and insertionpoints from that plugin will no longer be available

    Deleting a plugin will delete all assets from the server but will

    not remove data or database extensions

    Plugins are disabled when customizations is turned off

    84

    K P i t f T d Cl

  • 5/19/2018 Custom 501 Pre So

    85/88

    Key Points from Todays Class

    Database extensions Remember to plan and test thoroughly

    One-to-One Table Extensions Add a new data element to a

    parent table

    One-to-Many Tables Create a child table that is designatedto a parent table

    Standalone Tables Create a table that is not directly related

    to another table

    85

    K P i t f T d Cl

  • 5/19/2018 Custom 501 Pre So

    86/88

    Key Points from Todays Class

    Page Fragments are small snippets of code to be inserted into

    insertion points

    Insertion points are part of PowerSchool core, but may also

    be created

    Page Fragments are inserted into files based on the filename

    of the fragment

    jQuery makes insertion points much more flexible

    Plugins allow for customizations to be packaged into a singlefile for installation on other servers

    86

    Q ti d A

  • 5/19/2018 Custom 501 Pre So

    87/88

    Question and Answer

    87

    D t F t!!

  • 5/19/2018 Custom 501 Pre So

    88/88

    Dont Forget!!

    Navigate to

    http://powerschooluniversity.com

    and tell us what you think!

    http://powerschooluniversity.com/