diff --git a/docs/student/best-practices/DeterminingAccountBalances.md b/docs/student/best-practices/DeterminingAccountBalances.md new file mode 100644 index 00000000..d56d191d --- /dev/null +++ b/docs/student/best-practices/DeterminingAccountBalances.md @@ -0,0 +1,83 @@ +--- +title: "Determining Account Balances for Students" +id: studentapi-accountbalance-details +sidebar_position: 1 +author: Jim Burns +published: "" +edited: "" +--- + + + +One of the common use cases for integrators is to determine an account balance for a student. There are several different types of balances that may need to be retrieved. There are overall balances such as overall account balance for the student and an overall balance for a specific enrollment record for a student. There is also a balance for a subsidiary ledger for a student. And finally, there are use cases where an account balance for a specific term for a student needs to be determined. This document will cover these use cases and provide the details on how to return/calculate these balances using the Anthology data model. + +For the use cases where an overall balance for a student, enrollment or subsidiary ledger is needed, a simple odata query can be used. If the requirement is to calculate a balance for a given term, then the logic will be more complex and potentially require multiple odata queries with additional calculations needed on the returned data. + +## Account Balance for a Student or Student Enrollment Period record + +The overall account balance for a student is stored on the student master record (Student entity). The property that stores this balance is ArBalance. This property is recalculated every time there is any transaction posted to the student's ledger card. This balance will reflect the overall AR balance for the student regardless of which student enrollment period each individual transaction on the ledger card is associated to. To retrieve this balance you only need to know the StudentId value for the student: ds/odata/Students?$filter=Id eq ########&$select=ArBalance where ######## is the Id of the Student record the balance is being retrieved for. + +The overall account balance for a student enrollment period is stored on the student enrollment period record (StudentEnrollmentPeriod entity). The property that stores this is AccountReceivableBalance. The property is recalculated every time there is any transaction posted to the student's ledger card that is associated to the StudentEnrollmentPeriod record. A Student can have multiple enrollments. The AR Balance for each enrollment will be stored in this property: ds/odata/StudentEnrollmentPeriods?$filter=Id eq #######&$select=AccountReceivableBalance where ####### is the Id of the StudentEnrollmentPeriod record the balance is being retrieved for. + +## Account Balance for a Subsidiary Ledger + +Subsidiary Ledgers is a feature in Anthology Student that allows for separate ledgers to be created that are isolated from the transactions posted to a student's main ledger card. Student Subsidiary ledgers are associated at the StudentEnrollmentPeriod entity level. The entity that stores the ledgers being tracked for students is StudentSubsidiaryAccount. If you want to see all subsidiary ledgers for a given student you can use the SubsisiaryAccount navigation property on the StudentEnrollmentPeriod entity: ds/odata/StudentEnrollmentPeriods?$expand=SubsidiaryAccount + +Once the subsidiary ledger you need the balance for is identified, you just need to retrieve the value in the AccountBalance property on the StudentSubsidiaryAccount record. + +## Account Balance for a term + +Account Balances for specific terms are not persisted anywhere in the Anthology Student data model and will need to be calculated. At a high level, the calculation logic will need to isolate transactions for the specific term the balance is being calculated for and then sum the debits/credits in order to derive the balance. The logic needed for this will vary depending on how the client is utilizing the Apply Payments feature. There are configuration options that specify if payments will be auto applied to charges when posted, the effective date of the auto apply logic, details on the order of how payments are applied etc. At a high level, there are 2 key configuration data points that must be determined in order to decide the best logic to use for calculating the term balance. The first is to determine if payments are being auto applied. This is a campus specific setting. When set to auto apply, any payment or credit adjustment transaction that is posted will be automatically applied to charge transactions using the Credits Apply Order configuration. If not set to auto apply, then each payment transaction and credit adjustment transaction will have to be manually applied by the user. If this is not done, then the apply payment details will not exist for a given payment/credit adjustment transaction. Navigate to Settings - Campuses - Student Accounts to see this setting. + +![AccountBalances](/assets/img/AccountBalances1.png) + +The value of this setting is stored in the ApplyPaymentsMethod property on the Campus entity. To retrieve this setting value for a given campus: ds/odata/Campuses?$filter=Id eq ######&$select=ApplyPaymentMethod where ###### is the Id of the Campus the setting value is being retrieved for. Use the CampusId on the Student entity record if the scope of the balance calculation is at the Student level. Use the CampusId on the StudentEnrollmentPeriod entity record if the scope of the balance calculation is at the StudentEnrollmentPeriod level. + +If the setting to auto apply is turned on, then a determination needs to be made as to if a payment is allowed to be applied to a different term than the term the payment transaction itself is associated to. This is configured within the Credits Apply Order option. To access, navigate to Configuration - Student Accounts - Credits Apply Order. This specific setting is set at the apply line item level meaning that it can vary between credit billing codes/fund sources. + +![AccountBalances](/assets/img/AccountBalances2.png) + +If the Basis is set to Payment Period, then any payments/credit adjustments posted for the specified fund source/credit adjustment billing code can only be applied to other charge transactions that are associated to the term that the given payment transaction is associated to. If a different Basis is selected, then the payment/credit adjustment transaction can be associated to charge transactions for different terms. + +NOTE: There are some built-in rules that cannot be controlled via configuration that could cause payments to be applied to different terms even when the selected Basis is "Payment Period". This could result in an incorrect balance calculation when using ONLY the StudentAccountTransaction entity (see balance calculation logic options below) even when the configured Basis is "Payment Period". Thus it is recommended to implement the Balance calculation using BOTH StudentAccountTransaction and StudentAccountTransactionAppliedPayment entities if the setting to Auto Apply payments is set for a given campus. If the payment apply setting for a campus is "Manual/User Applied", then the best logic to use for calculating the term account balance will need to be worked out with the client. If it cannot be assumed that accurate payment apply details are stored in the StudentAccountTransactionAppliedPayment entity, then logic using ONLY the StudentAccountTransaction entity must be used. + + +### Balance calculation logic using ONLY the StudentAccountTransaction entity + +The first step for calculating the term account balance will be to retrieve all rows from the StudentAccountTransactions entity for the term the balance is being calculated for. Additionally, if the scope of the balance calculation is the Student, then an additional filter on StudentId will be needed: ds/odata/StudentAccountTransactions?$filter=StudentId eq ####### and TermId eq 99999999 where ######## is the student id you are filtering on and 99999999 is the term id of the term the balance is being calculated for. + +If the scope of the balance calculation is a specific student enrollment period, then an additional filter on StudentEnrollmentPeriodId will be needed: ds/odata/StudentAccountTransactions?$filter=StudentEnrollmentPeriodId eq ####### and TermId eq 99999999 where ######## is the student enrollment period id you are filtering on and 99999999 is the term id of the term the balance is being calculated for. + +Using the result set from the above query, you can then calculate the account balance. Sum the TransactionAmount property for all rows where Type is equal to D or I. Then sum TransactionAmount property for all rows where Type is equal to C or P. Subtract this summed amount from the sum of all rows where Type is equal to D or I. This will be the term account balance. + + +### Balance calculation logic using BOTH the StudentAccountTransaction and StudentAccountTransactionAppliedPayment entities + +The first step for calculating the term account balance will be to retrieve all charge transactions from the StudentAccountTransaction entity for the term the balance is being calculated for. Additionally, the filter needs to include whether it is for the student or a specific student enrollment period (see above). Odata query using student as the scope would be: ds/odata/StudentAccountTransactions?$$filter=StudentId eq ######### and TermId eq 99999999 and (Type eq 'I' or Type eq 'D'). + +Using the result set returned from the query above, sum the TransactionAmount property for all rows. This is the total amount of charges for the term. The next step is to reduce the balance by the amount of payments/credits that have been applied against each of these charges. The amount of applied payments to a given charge transaction can be determined by retrieving all rows from the StudentAccountTransactionAppliedPayment entity where AppliedToStudentAccountTransactionId equals the Id of the StudentAccountTransaction charge record being evaluated. Since multiple payments can be applied to a single charge, there may be multiple rows in the StudentAccountTransactionAppliedPayment entity that have amounts applied to the given charge transaction. Sum the AppliedAmount value for all rows returned. Perform this calculation for each charge transaction returned from the StudentAccountTransaction query above. Once the total applied amount for all charges has been calculated subtract this from the total amount of charges calculated for the term. The result is the account balance for the term. + +NOTE: There is an AmountPaid property on the StudentAccountTransaction entity. The intent is that this property will store the amount of applied payments/credits that have been applied to the charge. This property can be used to greatly simplify the processing logic needed to calculate the term account balance. However, there have been instances in the past whereby this property has not always been correctly maintained and does not reconcile to the specific payment apply details in the StudentAccountTransactionAppliedPayment entity. This is why it is recommended to utilize the data in the apply payment entity itself as opposed to using the amount stored on this property. + + +## Authorization + +In order to execute the OData queries needed for retrieving the data to calculate account balances, proper authorization needs to be configured. Whether using Basic Auth or OAuth with application key to authenticate, the user context the OData queries are executing under will be a user record from the Staff entity. This is the user that authorization needs to be configured for. Access to the security console application is needed in order to set the needed permissions. + +The authorization model for the odata endpoint is to either grant permission to query all entities contained within the query data model or to authorize each individual entity that data will be extracted from. Currently there are no tasks available for authorizing by business area or domain. Best practice is to NOT authorize access to the entire query data model so it will be necessary to create an inventoried list of each entity that data will be retrieved from and add the applicable operation for the user. In order to authorize at the operation level, select the role that the user is a member of. Then select Add Permissions. On the resulting page that is displayed, check the Show Operations checkbox. To make the resulting list easier to navigate, you may want to uncheck the Show Tasks, Show Built In Tasks and Show Roles check boxes. Click Apply. + +![AccountBalances](/assets/img/AccountBalances3.png) + +All of the odata query model operations are named as follows: domain + entity name (singluar) + query. So to authorize the permission to retrieve data from the BillingCodeTransaction entity, the StudentAccounts.BillingTransactionCode.Query operation would need to be added for the user. + +![AccountBalances](/assets/img/AccountBalances4.png) + +For the queries discussed in this document, the minimum authorization for the authenticated user will be to the Student, StudentEnrollmentPeriod, StudentAccountTransaction, StudentAccountTransactionAppliedPayment, StudentAccountTransactionConfigureAppliedPayment and Campus entities. Additional entities may be needed depending on the specific use cases being implemented. + +## Conclusion + +As can be the case, there may be additional nuances for how to calculate account balances that best match up to the use case at hand that are not covered within this document. + +If there are questions after reviewing this document, you can submit them by sending an email to developers@anthology.com. + + \ No newline at end of file diff --git a/docs/student/best-practices/ManageClassSections.md b/docs/student/best-practices/ManageClassSections.md new file mode 100644 index 00000000..a63ff8e9 --- /dev/null +++ b/docs/student/best-practices/ManageClassSections.md @@ -0,0 +1,308 @@ +--- +title: "Managing Class Sections via APIs" +id: studentapi-classsectionapi-details +sidebar_position: 1 +author: Jim Burns +published: "" +edited: "" +--- + + + +Creating and managing class sections is a fundamental requirement for the Academics domain within Anthology Student. Several different use scenarios exist whereby external applications have a need to create and update data for a class section. This data can be the class section data itself or peripheral data such as class section meeting schedules, instructor assignments to a class section, meeting location data, cross referenced class sections etc. This document will outline the various APIs available within Anthology Student that can be utilized to manage class section data. + +This document will cover the following endpoints: + +api/commands/Academics/ClassSection/SaveNew +api/commands/Academics/ClassSection/Save +api/commands/Academics/ClassSection/SaveClassSectionPeriods +api/commands/Academics/ClassSection/SaveInstructorAndPortalOptions +api/commands/Academics/ClassSectionMeetingDate/SaveNew +api/commands/Academics/ClassSectionMeetingDate/Save +api/commands/Academics/CrossListClassSection/SaveCrossListClassSection + + +## Data model notes + +There are multiple entities that store the data for class sections. Below is a list of the relevant entities that will be updated within the API endpoints this document will cover. + +ClassSection - This is the main entity for class section data. There will be 1 row per class section stored in this entity. All other entities listed are child entities and will be associated to this entity via the ClassSectionId property or another Id property for an entity that is associated to the ClassSection record via the ClassSectionId property. + +ClassSectionTerm - This entity holds the term that the class section is offered in. There is a separate entity for this because at one point in time it was possible for a class section to be associated to more than 1 term. This is no longer the case. So, each ClassSection instance will have 1 associated row in this entity. The TermId will hold the Id of the term the class section is being offered in. + +ClassSectionSecondaryInstructor - This entity will store the secondary instructors associated to the class section. The primary instructor is stored in the InstructorId property on the ClassSection record. If there are any additional instructors to assign to the class section besides the primary instructor, they will be stored in this entity. + +CrossListClassSectionGroup, CrossListClassSection - If class sections are cross listed with each other, then these entities will store the details of the cross listing. The CrossListClassSectionGroup will store the header record for the group of class sections cross listed with one another. The CrossListClassSection entity will store one row for each class section in the group of cross listed class sections. + +ClassSectionInstructorAttribute - If utilizing the instructor attributes feature, then this entity will be populated with the associated attributes for each instructor assigned to the class section. + + +The entities listed below will hold data related to class section meeting schedules and individual class section meetings. For class sections that are student self paced and do not have any scheduled meetings where all registered students are required to attend, then there will likely be no data in the entities listed below. + +ClassSectionMeetingPattern - This entity will hold one row for each recurring meeting pattern that is specified for a class section. When choosing a meeting pattern, the user can either select from a pre-configured meeting pattern (ds/odata/MeetingPatterns) or create one on the fly. If selected from one of the configured meeting patterns, then the MeetingPatternId property will store the Id of the MeetingPattern row that was selected. The value of the Type property will be 'L'. If a meeting pattern is entered on the fly, then the MeetingPatternId property will store the Id of the ClassSectionCustomMeetingPattern row that stores the summary data of the meeting pattern entered (see below). The value of the Type property will be 'D'. IMPORTANT NOTE: There are two navigation properties defined that both use the MeetingPatternId property. The MeetingPattern navigation property expands to the MeetingPattern entity. The CustomMeetingPattern navigation property expands to the ClassSectionCustomMeetingPattern entity. In order to retrieve expected result sets, you MUST use a filter on the Type property. When utilizing the MeetingPattern navigation property, you need to filter on rows where Type equals 'L'. When utilizing the CustomMeetingPattern navigation property you need to filter on rows where Type equals 'D'. + +MeetingPattern, ClassSectionCustomMeetingPattern - these entities store meta data for the recurring meeting pattern. Days of week meetings will be on, when does recurring meeting pattern start relative to class section start date, duration of recurring meeting pattern etc. As discussed above, the pre-configured meeting patterns will be stored in the MeetingPattern entity. Recurring meeting patterns created on the fly while building out a class section will be stored in the ClassSectionCustomMeetinPattern entity. + +ClassSectionMeetingSchedule - This entity will hold one row for each day of the week specified in each of the recurring meeting patterns configured for the class section. This is the entity that stores the detail of each recurring meeting such as Instructor, Length of meeting, start/end time of meeting, location of meeting and day of week that the meeting occurs on. The DayOfWeek property specifies which day of the week the recurring meeting will occur. This is an Enum with the following values: 1=Sunday, 2=Monday, 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday + +ClassSectionMeetingDate - this entity stores 1 row for each meeting instance for a class section. When a meeting pattern is specified for a class section, the daily meeting dates will be derived from the meeting patterns and 1 row per scheduled meeting will be inserted into to this entity. Additional meeting date records can be added and/or existing meeting date records can be edited. + + + +## Swagger documentation + +To access the Swagger documentation, append 'swagger' to the end of the base URI that is used to launch the Anthology Student web client application. Once the Swagger landing page is loaded, use the Domain and Functional Area drop down filters at the top of the swagger page to access the documentation. To access the API endpoints mentioned above, select 'Academics' for Domain and 'Class Section Scheduling' for Functional Area and then select Refresh. Find the ClassSection, ClassSectionMeetingDate and CrossListClassSection entities in the displayed list of entities and then click the lightning bolt icon. The list of APIs for each of these entities will be listed. Find the applicable API operation in the displayed list. + +![ManageClassSections](/assets/img/ManageClassSections1.png) + +![ManageClassSections](/assets/img/ManageClassSections2.png) + + +## Request payloads + + +### Creating and Updating a ClassSection record + +api/commands/Academics/ClassSection/SaveNew +api/commands/Academics/ClassSection/Save + +The request payload for these endpoints is the ClassSection entity. As a best practice, when using these endpoints, the api/commands/Academics/ClassSection/Create should be used in conjunction with SaveNew and the api/commands/Academics/ClassSection/Get should be used in conjunction with Save. See "Tips for Using the Get and Save API Operations" and "Tips for Using the Create and SaveNew API Operations" articles for more info. + +The minimum required properties for saving a new class section is listed below: + +- CampusId - populate with Id of campus the class section is being offered at + +- CourseCode - populate with the course code of the class section + +- CourseId - populate with the Id of the course of the class section + +- DeliveryMethodId - populate with the Id of the Delivery Method of the class section. Must be a valid reference to a row in the DeliveryMethod entity. + +- EndDate - populate with the end date of the class section + +- EnrollmentStatusClockHours, EnrollmentStatusCreditHours - populate with the number of credits and/or clock hours that will be used in the enrollment status (i.e. Full Time, Half Time etc.) calculation for a student. In the vast majority of cases, these values are inherited from the EnrollmentStatusClockHours and EnrollmentStatusCreditHours stored on the associated Course entity record (see CourseId above). + +- EntityState - populate with 0 if adding a new class section. 2 if updating an existing class section + +- Id - populate with -1 if adding a new class section. Existing Id value of row if updating a class section. + +- InstructorId - Id of Staff record for the primary instructor of the class section + +- IsActive - populate with 1 if adding class section + +- MaximumStudents - populate with max students allowed to be registered in class section + +- PassFailSetting - populate with 1 if NOT pass/fail, 2 if class section is pass/fail, 4 if it is student choice + +- PostAttendanceType - specify the type of attendance entry that will occur for this class section. Valid Values: P= Only Time Present will be entered A= Only Time Absent will be entered T= Both Time Present and Time Absent will be entered N= No Attendance will be entered + +- SectionName - populate with the course title + +- StartDate - populate with the start date of the class section + +- Terms - this is a collection property. Only 1 element will be added. + - TermId - Populate with Id of term class section is being offered in. + + - ClassSectionId - populate with -1 + + - EntityState - populate with 0 + +There are numerous other properties defined for the class section entity. These are optional. Depending on the specifics of the client requirements, some of the these optional properties may need to be populated in order to achieve the desired result when executing these APIs. + +### Managing Meeting Schedule data + +api/commands/Academics/ClassSection/SaveClassSectionPeriods + +This endpoint should be used for updating any aspect of the meeting schedule for the class section. The request payload includes some complex type properties. Details of how this payload should be populated are below. + +- IsContactHoursConfirmed - set this property to 1 if you want to override validation done on total contact hours scheduled for the class section. There is capability in Anthology Student to require the total daily meeting schedule for a class section to equal the expected contact hours total for the course the class section is for. If set to 0 and there is a conflict found, then a validation message will be returned. + +- IsRequireLDAConfirmed - this property does not impact execution logic within the API. However, if set to 0 and you are updating a meeting schedule for a class section AND at least 1 day of attendance has been posted for a scheduled meeting date, a validation message of type Warning will be returned in the response. It is recommended that you populate this with 1 so that the warning message will not be included in the response so as to not cause any unnecessary confusion. + +- IsScheduleConflictsConfirmed - set this property to 1 if you want to override any scheduling conflicts that are found and save the meeting schedule data as provided in the request. Conflict validation logic will check for conflicts in building/room scheduling as well as instructor conflicts. If set to 0, then the validation logic will execute and return a validation message if any conflicts are found. + +- ClassSectionId - populate with Id of class section the meeting schedule data is being updated for + +- ClassSection - this property is of type ClassSectionEntity and should be ignored. There are no dependencies within the execution logic of the API on any data in this property + +- MeetingPatterns - this property is a collection of type ClassSectionMeetingPatternEntity. + + - Id - populate with 0 if a new instance of ClassSectionMeetingPatternEntity is being created. Populate with Id of ClassSectionMeetingPatternEntity record if an existing instance + is being updated. + + - MeetingPatternId - if the recurring meeting pattern is a pre-configured meeting pattern, then set this to the Id of the MeetingPattern entity instance being used. If a new + recurring meeting pattern is being created, then set to 0. If an existing meeting pattern is being updated that was not created from a pre-configured meeting + pattern, then set to the Id value of the ClassSectionCustomMeetingPatternEntity that is being updated + + - Type - If the recurring meeting pattern is a pre-configured meeting pattern, then set to 'L'. If the recurring meeting pattern is not created from a pre-configured meeting + pattern, then set to 'D'. + + - ClassSectionId - populate with Id of class section the meeting schedule data is being updated for + + - DayOfWeekRooms - this is a complex type and is a collection. One element should be populated in this property for each day of week in the recurring schedule meeting pattern + + - DayOfWeek - This is an Enum with the following values: 1=Sunday, 2=Monday, 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday + + - BuildingId - populate with Id of Building that the scheduled meeting will occur in + + - RoomId - populate with Id of Room that the scheduled meeting will occur in + + - LocationId - populate with Id of Location that the scheduled meeting will occur in + + - PrimaryInstructorId - populate with Id of primary instructor that will be teaching this class section meeting + + - SecondaryInstructorList - this is collection property and should be populated with one element for each secondary instructor that will be teaching this class section + meeting. Only the InstructorId property in the element needs to be populated. + + - MeetingPattern - this is a complex type - ClassSectionCustomMeetingPatternEntity + + - StartTime - populate with the start time of the class section scheduled meeting. This is a datetime type. However, only the time portion of the value is relevant. + Populate the date portion of the value with "1899/12/30". + + - EndTime - populate with the end time of the class section scheduled meeting. This is a datetime type. However, only the time portion of the value is relevant. Populate + the date portion of the value with "1899/12/30". + + - IsMeetingOn properties - a boolean type property exists for each day of the week. Set the applicable bool properties to 1 for the days of the week that the class section + will be meeting on + + - Id - if the recurring meeting pattern is a pre-configured meeting pattern, then set this to the Id of the MeetingPattern entity instance being used. If a new recurring + meeting pattern is being created, then set to 0. If an existing meeting pattern is being updated that was not created from a pre-configured meeting pattern, then set + to the Id value of the ClassSectionCustomMeetingPatternEntity that is being updated + + - MeetingLength - set to the duration of the scheduled meeting in minutes + + - PatternType - W= Weekly, M= Monthly + + - Frequency - set to frequency of pattern type. For example, if pattern type is Weekly and recurring pattern is the same every week, then Frequency would be set to 1. If + recurring pattern is every other week, then Frequeny would be 2. + + - RecurrenceStartWeeks - if recurring meeting pattern will start sometime AFTER the class section begins meeting, then specify the number of weeks after the start of the + class section when the recurring meeting pattern will begin. If the meeting pattern begins when the class section starts, then set this value to 0. + + - RecurrenceEndNumber - if recurring meeting pattern will occur only a set number of times and not carry through to the end date of the class section, then set this value + to the number of times it will occur. Otherwise, set to 0. + +### Managing Secondary Instructor Assignments and Instructor attribute data + +api/commands/Academics/ClassSection/SaveInstructorAndPortalOptions + +This endpoint should be used to manage any changes in secondary instructor assignments or any applicable instructor attribute associations for this specific class section. NOTE: Although the primary instructor assignment is managed in the ClassSection SaveNew and Save endpoints discussed above, the class section instructor attribute data for the primary instructor is managed within this endpoint. Additionally if using the Faculty Workload Management module, the Staff Position Assignment can also be set for the primary instructor using this endpoint. + +When calling this endpoint, make sure the request is populated with each secondary instructor that should be assigned to the class section. This API behaves like a REST PUT action. Whatever is provided in the request will overwrite the existing secondary instructor assignments for the class section. + + +- ClassSectionId - set to the Id of the class section that instructor information is being updated for + +- HideFaculty - ignore. not used in API execution logic + +- HideLocation - ignore. not used in API execution logic + +- Instructors - this is a collection property and will hold one element per instructor that is assigned to the class section. The primary instructor for the class section should always be in element 0. + + - Id - set this to the Id of the StaffEntity instance for the Instructor that is assigned to the class section + + - CanPostAttendance - Only applicable if this is a secondary instructor. If set to 1, the instructor will be able to post attendance for the class section. + + - CanPostFinalGrades - Only applicable if this is a secondary instructor. If set to 1, the instructor will be able to post final grades for the class section. + + - CanPostLessons - Only applicable if this is a secondary instructor. If set to 1, the instructor will be able to post lesson scores for the class section. + + - StaffPositionAssignmentId - Only applicable is using the Faculty Workload Management module. Set to the Id of the StaffPositionAssignmentEntity instance associated to this + instructor for this class section. + + - Attributes - this is a collection of int. Specify the Id of each InstructorAttribute (ds/odata/InstructorAttributes) that is associated to the instructor for this class section. + +### Managing data for individual scheduled class section meetings + +api/commands/Academics/ClassSectionMeetingDate/SaveNew +api/commands/Academics/ClassSectionMeetingDate/Save + +These endpoints allow for the creation and update of individual class section meeting dates. This is useful if there are any exceptions to the class section recurring meeting schedules for the class section. + +The request payload for these endpoints is the ClassSectionMeetingDate entity. As a best practice, when using these endpoints, the api/commands/Academics/ClassSectionMeetingDate/Create should be used in conjunction with SaveNew and the api/commands/Academics/ClassSectionMeetingDate/Get should be used in conjunction with Save. See "Tips for Using the Get and Save API Operations" and "Tips for Using the Create and SaveNew API Operations" articles for more info. + +- IsMeetingScheduleConflicted - ignore. The value of this property is manipulated within the API execution logic + +- IsMeetingScheduleConflictOverridden - set to 1 if you want to override any scheduling conflicts that are found and save this meeting date record as provided in the request. Conflict + validation logic will check for conflicts in building/room scheduling as well as instructor conflicts. If set to 0, then the validation logic will + execute and return a validation message if any conflicts are found. + +- IsInstructorMeetingScheduleConflicted - ignore. The value of this property is manipulated within the API execution logic + +- ClassSchedPeriodDayConflictList - this is a complex type with multiple properties. This property has no bearing on any of the API execution logic so this can be ignored. + +- InstructorId - Id value of instructor record in the Staff entity that is teaching this class section meeting + +- InstructorList - This is an array of type int. Add 1 element per instructor that is teaching the class meeting. Populate with the Id value of instructor record in the Staff entity. + This allows for more than 1 instructor to be assigned for a single class meeting. If only 1 instructor is teaching the meeting, then this will have 1 element and be + populated with the Id value that the InstructorId property above is populated with + +- LoadTypeIdList - This is an array of type int. Only applicable if using the Faculty Workload Management module. Populate with one element per load type that will be associated to this + class section meeting. The Id value will reference the applicable row in the WlmLoadTypeEntity. + +- BuildingId - Id value of Building where class meeting will take place + +- ClassSectionId - Id value of the ClassSection the meeting is being added/updated for + +- ClassSectionMeetingPatternId - if adding a new meeting record, set this to null. If updating an existing meeting record, set this to the value returned when executing the Get command + API as the first step prior to executing the Save endpoint. This value should never be modified for an existing record. + + + +- EntityState - If adding new meeting record, set to 0. If updating an existing meeting record, set to 2. + +- Id - If adding a new meeting record, set to -1. if updating an existing meeting record, set to the Id of the ClassSectioMeetingDateEntity record being updated + +- IsManualEdit - if adding a new meeting record, set to 1. If updating an existing meeting record, set this to the value returned when executing the Get command API as the first step + prior to executing the Save endpoint. This value should never be modified for an existing record. + +- IsMeetingEdit - set to 0 + +- LengthMinutes - set to duration of class meeting in minutes + +- LocationId - Id value of Location where class meeting will take place + +- MeetingDate - date of meeting. This is DateTime type. However, only the date portion of the property value is relevant. i.e. "2024/05/28 00:00:00" + +- Note - if cancelling a class meeting, provide text for reason meeting is being cancelled + +- RoomId - Id value of Room where class meeting will take place + +- StartTime - time the class meeting will begin. This is DateTime type. Set date portion of property to the MeetingDate above and the Time portion to the start time of the class + meeting. i.e. "2024/08/29 07:30:00" + +- Status - If adding a new meeting record, set to 'S'. If cancelling a class meeting, set to 'C'. If updating an existing record without cancelling, then do not change the value. Use + the value returned when executing the Get command API as the first step prior to executing the Save endpoint. + +### Crosslisting Class Sections + +api/commands/Academics/CrossListClassSection/SaveCrossListClassSection + +This endpoint is used to update cross listing information for class sections. + +- ClassSectionId - Id value of Class Section being cross listed + +- CrossListClassSections - this property is an array of type int. Add 1 element for each class section the ClassSectionId above is being cross listed with. Populated with the Id value + for each class section being cross listed. + +- TermId - Id value of Term the ClassSectionId above is associated to + +- EntityState - set to 2 + +NOTE: When this API is executed, the class sections specified in the CrossListClassSections property will replace the class sections that are currently cross listed with the specified +ClassSectionId. Make sure that ALL of the class sections that should be cross listed with the specified ClassSectionId are provided in the CrossListClassSections property even if some are already saved as cross listed class sections. + + +## Authorization required for these API endpoints + +In order to be able to execute the API endpoints covered in this document, the user that the API call is authenticating under must have the Academics - Class Scheduling - Edit task included in the list of tasks/operations that the user is authorized to. This is done from the security console application. + +![ManageClassSections](/assets/img/ManageClassSections3.png) + +## Conclusion + +As is usually the case, there may be additional nuances for how to properly formulate the request for these APIs in order for them to produce the desired result that are not covered within this document. + +If there are questions after reviewing this document and the corresponding swagger documentation, you can submit them by sending an email to developers@anthology.com. + + \ No newline at end of file diff --git a/docs/student/best-practices/ManageCustomFields.md b/docs/student/best-practices/ManageCustomFields.md new file mode 100644 index 00000000..cb9a1d9d --- /dev/null +++ b/docs/student/best-practices/ManageCustomFields.md @@ -0,0 +1,127 @@ +--- +title: "Managing Custom Fields via APIs" +id: studentapi-customfields-details +sidebar_position: 1 +author: Jim Burns +published: "" +edited: "" +--- + + + +Creating custom fields for additional data capture is a key capability within the Anthology Student application. This capability was introduced many years ago and has evolved over time. The result is that there are three different implementations for configuring and managing data for custom fields in the application currently. The details for how to manage data for custom fields via APIs will depend on the specific entity that the custom fields are for. This document will outline each of the three implementations and identify which entities belong to each. Additionally, details on how to retrieve data as well as update data for custom fields will be covered. + +## School Defined Fields + +The original implementation of custom fields in Anthology Student is referred to as "School Defined Fields" or "School Fields". This implementation allows for any number of custom fields to be configured for the Student entity. Although not explicitly called out in configuration of School Defined Fields, the association of data for these fields will be on the Id property in the Student entity. The configuration includes the ability to specify which modules/domains a given field is visible in. To see additional details regarding this feature including how to configure, refer to Help which is accessible via the question mark icon on the top right portion of the toolbar in the web client UI. + +![ManageCustomFields](/assets/img/ManageCustomFields1.png) + +There is no API that has a single responsibility of managing data for School Defined Fields. The endpoints you will need to use for updating data for School Defined Fields are api/commands/Common/Student/SaveNew and api/commands/Common/Student/Save. The SaveNew operation is used when creating a new student record and the Save operation is used when updating an existing Student record. For additioal details on using the Save and SaveNew operations please refer to: + +[Tips for using Get and Save API Operations](https://docs.anthology.com/docs/student/best-practices/get-save-bestpractices) +[Tips for using Create and SaveNew API Operations](https://docs.anthology.com/docs/student/best-practices/create-savenew-bestpractices) + +The vast majority of use cases will be to update school defined fields data for an existing student. The remainder of this section will use the Save operation as an example. The first step will be to retrieve the instance of the Student record that school defined fields data is being update for. Execute the api/commands/Common/Student/Get operation. Existing data for the school defined fields for the student will be in the CustomProperties and/or MultiValueCustomProperties properties in the response. If a school defined field has been configured to allow multiple values to be specified, then the values for this school defined field will be contained in the MultiValueCustomProperties property. For single value custom properties (majority of school defined fields), the data will reside in the CustomProperties property. These properties are defined as a collection of key/value pairs. The only difference is that the value for the MultiValueCustomProperties is of type ICollection`` whereas the value type for the CustomProperties collection is string. The key contains the Code value for the configured school defined field. This value must match exactly to the Code value for the school defined field in order to be correctly updated (see screenshot below). + +![ManageCustomFields](/assets/img/ManageCustomFields2.png) + + +If there is a value being specified for a school defined field for the first time, then a new row will need to be added to the collection. If an existing value is being modified, then find the element for the applicable school defined field and update accordingly. One final note is that the data type is string. All values must be provided as a string type including any school defined fields that have been configured with a type of numeric or date. Once the applicable data has been updated in the CustomProperties and MultiValueCustomProperties properties, then execute the api/commands/Common/Student/Save endpoint to update. + +### Retrieving Data + +School Defined fields data is stored in the StudentSchoolDefinedFieldValues entity. To retrieve all school defined field values for a given student, a filter on the StudentId property would be used: ds/odata/StudentSchoolDefinedFieldValues?$filter=StudentId eq ####### where ####### is the Id of the Student to retrieve data for. + +If data for specific school defined fields is needed, then additional filtering would be done. There is a navigation property called SchoolDefinedField on the StudentSchoolDefinedFieldValues entity that expands to the school defined fields configuration entity (SchoolDefinedFields) which can be leveraged to include any additional filtering neded for retrieving the school defined field values. + +Lastly, there is a navigation property on the Student entity called SchoolDefinedFieldValues. You can include this in an expand statement to retrieve school defined field values data. i.e. ds/odata/Students?$expand=SchoolDefinedFieldValues + +## School Defined Fields - Course + +The original implementation of school defined fields was enhanced to allow for custom fields to be configured for the Course entity. The main difference between school defined fields for the Course entity verses school defined fields for the Student entity is that there is no configuration that allows for specifying where these school defined fields will be visible. ALL school defined fields that have been configured for a Course will be visible via the "School Fields" tile on the Course configuration page. Additionally, the entities that the course school defined field configurations and values are stored in were designed to support multiple entities. As it turns out, the Course entity was the only entity implemented. No additional work was ever done to support additional entities within this implementation. + +![ManageCustomFields](/assets/img/ManageCustomFields3.png) + +To update school defined field data for a course use the api/commands/Academics/Course/Save endpoint. The patterns to follow are the same as what is outlined for the Student entity above. + +### Retrieving Data + +School Defined fields data for the Course entity is stored in the EntitySchoolDefinedFieldValues entity. To retrieve all school defined field values for a given course, a filter on the RecordId property would be used: ds/odata/EntitySchoolDefinedFieldValues?$filter=RecordId eq ####### where ####### is the Id of the Course to retrieve data for. As noted above, the design of the configuration and value tables was created with the intent of supporting additional entities. This was never done. Thus, you can ignore the TableName property in any filtering requirements since every row in this entity will have a value of 'AdCourse'. + +If data for specific school defined fields is needed, then additional filtering would be done. There is a navigation property called EntitySchoolDefinedField on the EntitySchoolDefinedFieldValues entity that expands to the school defined fields configuration entity (EntitySchoolDefinedFields) which can be leveraged to include any additional filtering needed for retrieving the school defined field values for the Course. + + +## Extended Properties + +The newest implementation for managing data for custom fields is referred to as "Extended Properties". This implementation was done to easily enable new entities to support the ability to capture custom field data. Unlike the School Defined Fields explained above, there are dedicated API endpoints for managing data for extended properties. There are several entities that currently support this capability with additional entities being added on a regular basis. The best way to determine if a given entity has support for extended properties is to go to the Extended Properties configuration page and view the list of entities displayed in the Entity Type drop down list. + +![ManageCustomFields](/assets/img/ManageCustomFields4.png) + +There are several API endpoints that may include the ability for saving data for extended properties where this would be considered in context of the scope of work being updated. For example, the API request for posting a payment transaction includes an ExtendedProperties collection property. This is because the entity that is updated when posting a payment transaction (StudentAccountTransaction) is enabled for the Extended Properties capability. The implementation of this may vary. Use of these types of APIs for updating extended property data will need to be evaluated on a case by case basis and is outside the scope of this document. The API endpoints that will be covered here are: + +api/commands/Academics/ExtendedPropertyValue/saveExtendedProperty +api/commands/Admissions/ExtendedPropertyValue/saveExtendedProperty +api/commands/CareerServices/ExtendedPropertyValue/saveExtendedProperty +api/commands/Crm/ExtendedPropertyValue/saveExtendedProperty +api/commands/FinancialAid/ExtendedPropertyValue/saveExtendedProperty +api/commands/StudentAccounts/ExtendedPropertyValue/saveExtendedProperty +api/commands/StudentServices/ExtendedPropertyValue/saveExtendedProperty + +The endpoint to use from the list above will depend on which domain the entity you are updating extended properties for is defined in. If you are unsure, then one way to determine is to locate the entity in the Swagger documentation. The route for all API endpoints for the given entity will begin with api/commands/domain name. Once the correct domain has been determined then use that domain's extended property API endpoint. + +The request payload for each of the listed APIs above are identical. + +Id - Set this to the Id of the row in the entity that the extended properties are being updated for + +EntityName - Set this to the name of the entity that the Id value is referencing. IMPORTANT: This is the command model entity name. All entities defined in the command model end with a suffix of "Entity". So if extended property values are being updated for a row in the StudentCourse entity, the value for this property needs to be "StudentCourseEntity" -- not "StudentCourse". If an invalid value is provided for EntityName, a validation error will be returned with a message of "Invalid Entity Name". + +ExtendedProperties - This is a collection. There are 2 values that need to be provided for each row in the collection: + + Name - Set this to the name of the extended property that was configured. This must match exactly to the Name of the extended property (see screenshot below). + + Value - Set this to the value of the extended property. Note that this property is of type string. If the extended property type is numeric, date or boolean, then populate with the + string equivalent. The API execution logic will handle the needed type conversions for persisting the data into the extended property values table. + +![ManageCustomFields](/assets/img/ManageCustomFields5.png) + +There is no need to specify if the value for the extended property is being provided for the first time or not. Although there is an Id property defined for the ExtendedProperties collection, it can be ignored. The API execution logic will determine if there is an existing row for the extended property value being updated. If not, it will insert a new row. If there is an existing row, then the existing value will be replaced with the value specified in the request. + +### Retrieving Data + +Extended property values are all stored in a entity called ExtendedPropertyValues. Unless there is a need to retrieve extended property data for multiple entities in one query, it is not recommended to use this entity for data retrieval. Instead, there is a database view created for each entity that is enabled to support extended properties. The entity name in the query model for each of these views is ##########ExtendedProperties where ######### is the name of the entity. For example, the db view entity name for extended property values for the AreaOfStudy entity is AreaOfStudyExtendedProperties. A navigation property called ExtendedProperties will exist on every entity enabled to support extended properties. This allows for you to easily add filter conditions as well as include extended property values in any query where the base entity is an entity that is enabled to support extended properties. For example, to retrieve extended property values for all rows in the ClassSections entity, the odata query would look like this: ds/odata/ClassSections?$expand=ExtendedProperties + +## Authorization + +### School Defined Fields + +In order to manage data for school defined fields, the authenticated user must be authorized to the Common - Student - Edit and Common - Student - New tasks which is done in the Security Console application. + +![ManageCustomFields](/assets/img/ManageCustomFields7.png) + +### School Defined Fields - Course + +In order to manage data for school defined fields for the course entity, the authenticated user must be authorized to the Academics.Course.Save and Academics.Course.SaveNew operations which is done in the Security Console application. These operations are included in the Academics - Configuration - Manage task. + +![ManageCustomFields](/assets/img/ManageCustomFields9.png) + +However, authorization to all of the other configuration options in the Academics domain will be included if this task is authorized. It is recommended that the individual operations above be authorized explicitly. To do this, the authenticated user will need to be associated to a Role. Find the applicable Role and then click the Add Permissions option. Uncheck the Show Tasks, Show Built In Tasks and Show Roles check boxes. Check the Show Operations check box and then click Apply. + +![ManageCustomFields](/assets/img/ManageCustomFields8.png) + +Find the Academics.Course.Save and Academics.Course.SaveNew operations, highlight each and click Ok. + +### Extended Properties + +There is capability for securing configured extended properties on an individual property basis. If the property is configured to require authorization, then the authenticated user executing the API must be a member of a staff group that has Edit permission enabled for the property. There is no work needed in the Security Console application for this. + +![ManageCustomFields](/assets/img/ManageCustomFields6.png) + + +## Conclusion + +As can be the case, there may be additional nuances for how to properly manage extended property data to address a client's specific use cases that are not covered within this document. + +If there are questions after reviewing this document and the corresponding swagger documentation, you can submit them by sending an email to developers@anthology.com. + + \ No newline at end of file diff --git a/docs/student/best-practices/ManageEnrollmentAreasOfStudy.md b/docs/student/best-practices/ManageEnrollmentAreasOfStudy.md new file mode 100644 index 00000000..85db6b45 --- /dev/null +++ b/docs/student/best-practices/ManageEnrollmentAreasOfStudy.md @@ -0,0 +1,93 @@ +--- +title: "Managing Areas of Study for a Student Enrollment record via APIs" +id: studentapi-enrollmentareaofstudyapi-details +sidebar_position: 1 +author: Jim Burns +published: "" +edited: "" +--- + + + +One of the key data points for a student enrollment period record in Anthology Student are the area of studies that are associated to the enrollment record. Every student enrollment period record must be enrolled in a program version. However, in many instances additional areas of study are added which bring additional requirements for the student in order to fully complete and graduate from their enrollment. It is common for students to modify associated areas of study during initial enrollment creation as well as after the enrollment record has been created. This document will cover the details of how to manage associated areas of study to an enrollment record using the available command APIs. Two API endpoints will be referenced in this document. The first is the API that is used to create a new student enrollment period record - api/commands/Academics/StudentEnrollmentPeriod/enrollStudent. The second is an API that can be used to modify the list of associated Areas of Study to an existing student enrollment period record - api/commands/Academics/updateStudentEnrollmentAreaOfStudy. + +## Data model notes + +StudentEnrollmentPeriod is the entity that holds the data for a student enrollment period. StudentAreaOfStudy is the entity that stores the data for each area of study that is associated to the student enrollment. A StudentEnrollmentPeriod can have 0, 1 or many associated rows in the StudentAreaOfStudy entity. To retrieve area of studies that are associated to a given student enrollment period, an odata query can be executed: ds/odata/StudentAreasOfStudy?$filter=StudentEnrollmentPeriodId eq ####### where ###### is the Id of the StudentEnrollmentPeriod record you are retrieving areas of study for. + +AreaOfStudy is the entity that stores the list of Concentrations/Areas of Studies that have been configured. To retrieve additional data for a given area of study when retrieving data from the StudentAreasOfStudy entity, expand to the AreaOfStudy navigation property in the odata query being executed. To see all of the areas of study that have been configured: ds/odata/AreasOfStudy (NOTE: When constructing odata queries, entities must be referenced using their plural name - in this case AreasOfStudy -- not AreaOfStudy) + +ProgramVersionAreaOfStudy - this entity stores the list of Areas of Study that are associated to each program version. The areas of study that are available to select for a given student enrollment record will be restricted to only those areas of study that are configured for the program version the student is enrolled into. To retrieve areas of study configured for a given program version: ds/odata/ProgramVersionAreasOfStudy?$filter=ProgramVersionId eq ####### where ####### is the Id of the program version you are retrieving associated areas of study for. + +## Swagger documentation + +To access the Swagger documentation, append 'swagger' to the end of the base URI that is used to launch the Anthology Student web client application. Once the Swagger landing page is loaded, use the Domain and Functional Area drop down filters at the top of the swagger page to access the documentation. To access the API endpoints mentioned above, select 'Academics' for Domain and 'Student Enrollment' for Functional Area and then select Refresh. Find the StudentEnrollmentPeriod entity in the displayed list of entities and then click the lightning bolt icon. The list of APIs for this entity will be listed. You will see enrollStudent and updateStudentEnrollmentAreaOfStudy in the displayed list of operations. + +![ManageEnrollmentAreasOfStudy](/assets/img/ManageEnrollmentAreasOfStudy1.png) + +![ManageEnrollmentAreasOfStudy](/assets/img/ManageEnrollmentAreasOfStudy2.png) + +## Request payloads + +The request payload for the enrollStudent endpoint is very large as this is used for creating a new enrollment period record. The request payload for the updateStudentEnrollmentAreaOfStudy endpoint is much smaller since this API has a single responsibility of updating associated areas of study for the existing student enrollment period record. Both requests however contain a collection property called programVersionAreaOfStudyConfigList. It is this property that will be the focus of this document as this is where the information for the associated areas of study is specified. Additional notes on the request payload for updateStudentEnrollmentAreaOfStudy will also be outlined below. + +programVersionAreaOfStudyConfigList[] + +- pkId – This property is only applicable when using the UpdateStudentEnrollmentAreaOfStudy endpoint and you are updating an existing area of study or removing an area of study. This can be ignored if using the enrollStudent endpoint. If updating or removing an area of study record for the student enrollment, then set this to the Id of the applicable row in the StudentAreaOfStudy entity that is being updated/removed + +- adConcentrationId – Populate this with the Id of Area of Study being added, updated or removed. This should only be applicable when adding a new area of study for a student. However, it is safest to populate with the applicable Id even if you are updating or removing an existing associated area of study in case there are any dependencies on this value within the API execution code. + +- code – Ignore. Not used in execution logic + +- descript – Ignore. Not used in execution logic + +- adMajorId – If adding new area of study and the new area of study is a child of an existing student area of study, then set this to the Id of the StudentAreaOfStudy record that the new area of student will be a child of. This use case can exist if there is an existing area of study record for the student were the Area of Study Type is MAJOR. Areas of Study that are Majors can have child areas of study. This property will only be applicable for the updateStudentEnrollmentAreaOfStudy endpoint since there must be an existing StudentAreaOfStudy row that is referenced by this Id. + +- adMajorCode – Ignore. Not used in execution logic + +- selListId – Id of the ProgramVersionAreaOfStudy entity record (see Data Model notes above) for the Program version that has the Area of Study (see adConcentrationId above) being added/updated for the student. In order to associate an area of study to the student enrollment record, the area of study must be configured as an available area of study to select for the program version the student is enrolled into. + +- typeId – Ignore. Not used in execution logic + +- typeCode – Ignore. Not used in execution logic + +- typeDescrip – Ignore. Not used in execution logic + +- mode – 1= New area of student record is being associated, 2= Existing Area of student record is being updated, 3= Existing Area of Study is being removed. Mode will always be 1 when using the EnrollStudent endpoint. NOTE: If removing an area of study from a student enrollment, the data update that will occur will be to change the value of the IsActive property on the StudentAreaOfStudy record to 0 as well as an update to the DropDate property. There is no property in the request payload for DropDate. The DropDate will be updated to the system date. + +- AdprogramVersionId – Ignore. Not used in execution logic + +- adCatalogYearId – Ignore. Not used in execution logic + +- effectiveDate – Effective date of the Area of Study record for the student. When using the EnrollStudent endpoint, this would be the StartDate of the new enrollment record being created. When using the updateStudentEnrollmentAreaOfStudy endpoint, this would be the date that the student declared for the area of study. + +### Other properties in the UpdateStudentEnrollmentAreaOfStudy request + +- EnrollId - populate this with the Id of the StudentEnrollmentPeriod record you are updating areas of study for + +- CampusId - populate this with the CampusId value from the StudentEnrollmentPeriod record you are updating areas of study for + +- ProgramVersionId - populate this with the ProgramVersionId value from the StudentEnrollmentPeriod record you are updating areas of study for + +- SchoolStartDateId - if the system setting to require start dates is set to true, then a value must be provided for this property. To determine the value of this setting, execute this odata query: ds/odata/CampusNexusStudentSettings?$filter=SettingName eq 'versionStartDateRequired'&$select=SettingValue. If the value of 1 is returned, then a value for SchoolStartDateId must be provided. The value can be determined using this odata query: ds/odata/SchoolStartDates?$select=Id&$filter=ProgramVersionId eq ######## and StartDate eq 99/99/9999 where ####### is the ProgramVersionId value and 99/99/9999 is the StartDate value from the StudentEnrollmentPeriod record you are updating areas of study for. + +- FilterTypes - In order for the API execution logic to work as desired, this property must be populated with the Id value of each row in the AreaOfStudyType entity. The property is defined as List of type int. To see the Id values for the AreaOfStudyType entity,execute ds/odata/AreaOfStudyTypes?$select=Id + +- CatalogYearId - populate this with the CatalogYearId value from the StudentEnrollmentPeriod record you are updating areas of study for + +- IsUpdateAreaOfStudy - make sure this is populated with 1. If not, then no data will be updated when executing the API. + + +## Authorization required for this API endpoint + +In order to be able to execute these API endpoints, the user that the API call is authenticating under must have the Academics - Student Enrollment Period - New task included in the list of tasks/operations that the user is authorized to. This is done from the security console application. + +![ManageEnrollmentAreasOfStudy](/assets/img/ManageEnrollmentAreasOfStudy3.png) + +## Conclusion + +As is usually the case, there may be additional nuances for how to properly formulate the request for these APIs in order for them to produce the desired result that are not covered within this document. + +If there are questions after reviewing this document and the corresponding swagger documentation, you can submit them by sending an email to developers@anthology.com. + + \ No newline at end of file diff --git a/docs/student/best-practices/PaymentReversalUsingAPI.md b/docs/student/best-practices/PaymentReversalUsingAPI.md new file mode 100644 index 00000000..b45c6813 --- /dev/null +++ b/docs/student/best-practices/PaymentReversalUsingAPI.md @@ -0,0 +1,71 @@ +--- +title: "Payment Reversals using APIs" +id: studentapi-paymentreversal-details +sidebar_position: 1 +author: Jim Burns +published: "" +edited: "" +--- + + + +A common use case for integrators is the need to reverse a payment received. Alternative terminology for a payment reversal can be to void the payment, refund the entire payment or refund a portion of the payment that was received. The correct way to handle via the Anthology Student APIs will depend on the specific use case/requirement the integrator needs to achieve. The two APIs that will be covered within this document are api/commands/StudentAccounts/StudentAccountTransaction/voidAccountTransactionPayment and api/student-accounting/ledger-refund-transactions. The voidAccountTransactionPayment API can be used ONLY if the entire payment is being reversed. The ledger-refund-transactions can be used for full or partial payment reversals. Details of using each of these APIs are outlined below. + +## api/commands/StudentAccounts/StudentAccountTransaction/voidAccountTransactionPayment + +This API should be used for the use case where a payment that was received is being 100% reversed. As stated above, if the use case is to partially reverse a payment, then this API should NOT be used. The unit of work within this API will be to post a new transaction on the ledger card that reverses the original received payment transaction. Additionally, there is capability to post an additional charge (if configured) for any NSF fees that will be charged to the student. See the Auto Charges option in Configuration - Student Accounts for more information on how to auto charge a NSF fee when a payment transaction is voided. + +The request payload for this endpoint is quite small and simple to work with. However, a few important notes need to be made. First is that there is a StudentSubsidiaryAccountTransactionId property defined in the request. This should be completely ignored. This endpoint can ONLY be used for voiding a payment transaction on the main ledger card. If the use case is to void a payment transaction on a subsidiary ledger, then a different API needs to be used: +(api/commands/StudentAccounts/StudentSubsidiaryAccountTransaction/voidSubsidiaryAccountPayment). The remainder of the request needs to be populated as follows: + +- StudentAccountTransactionId - set to the Id value of the payment transaction that is being voided. This property is required and must reference a transaction that is a payment and has not previously been voided. NOTE: If Anthology Student is integrated with the Anthology Finance application AND the payment transaction has already been reconciled within the Bank Reconciliation feature within the Finance application, then the payment transaction will not be allowed to be voided and a validation message will be returned. + +- StudentId - set to the StudentId value on the StudentAccountTransaction row that is being voided + +- StudentEnrollmentPeriodId - set to the StudentEnrollmentPeriodId value on the StudentAccountTransaction row that is being voided + +- Note - set to a comment that provides the reason this payment transaction is being voided. This property is required. If an empty string is provided, then a validation message will be returned stating this property is required. + +- ContinueIfAmountLessThanRefund - validation exists within the API that will recalculate the net amount received for the StudentAward record that the payment transaction being voided is associated to if applicable. If the StudentAwardId property on the StudentAccountTransaction row being voided is null or 0, then this validation logic is not applicable. If the net amount received for the StudentAward will be less than 0 after this payment is voided, then setting this property to 0 in the request will prevent the payment from being voided and return a validation message. + +- IsPreviousYear - if the payment transaction being voided was reported on a 1098T tax form for a prior year, then set this value to 1. + +### Other Notes + +If the Fund Source Security feature is being used and the payment transaction being voided is associated to a StudentAward record (see above), then the user that the API call is being authenticated under must have Void permission set for the fund source associated to the StudentAward record. If not, then a validation message will be returned and the payment transaction will not be able to be voided. + +![PaymentReversal](/assets/img/PaymentReversalUsingAPI1.png) + +If the payment transaction being voided is associated to a payment plan, then the payment plan will beadjusted to reflect the voided payment transaction as part of the unit of work. Total amount received towards the payment plan will be reduced. Additionally, the payment installment schedule will also be updated to show the expected payment(s) the payment being voided was associated to as being expected and not received. + +## api/student-accounting/ledger-refund-transactions + +This API can be used to partially or fully reverse a payment. If fully reversing a payment, it is important to understand the different behavior when using this API verses the void payment transaction endpoint discussed above. The key difference is that if reversing a payment received for a payment plan, there will be no logic executed within this API that will auto adjust the installment payment plan schedule. Although the total amount refunded for the payment plan header record (StudentAward entity) will be updated, the detailed payment schedule will not. Therefore, if a full payment that was made against a payment plan is being reversed, then it is recommended to use the VoidAccountTransactionPayment API discussed above. + +This API endpoint is well documented in the Swagger file. Thus, details on how to populate the request payload will not be provided here. To access this API in Swagger, select 'Integration' in the Type dropdown and then click Refresh. + +![PaymentReversal](/assets/img/PaymentReversalUsingAPI2.png) + +Select Student Accounting and then you will see the ledger-refund-transactions endpoint towards the middle of the page. + +![PaymentReversal](/assets/img/PaymentReversalUsingAPI3.png) + +A common validation message that is received when using this API endpoint is "Refund amount cannot exceed .......". There is another article (Refund Amount API Validation) that explains the details behind this validation message and the steps needed to resolve. + + +## Authorization + +In order to execute the APIs that have been discussed above, proper authorization needs to be configured. Whether using Basic Auth or OAuth with application key to authenticate, the user context the APIs are executing under will be a user record from the Staff entity. This is the user that authorization needs to be configured for. Access to the security console application is needed in order to set the needed permissions. In order to execute the VoidAccountTransactionPayment API, the user must be authorized for the Student Accounts - Student Account Transaction - Edit task. + +![PaymentReversal](/assets/img/PaymentReversalUsingAPI4.png) + +In order for the user to execute the ledger-refund-transactions API, the user must be authorized to the API - Student Accounting task. + +![PaymentReversal](/assets/img/PaymentReversalUsingAPI5.png) + + +## Conclusion + +There can likely be additional nuances/details around utilizing the these APIs that are not covered within this document. If there are any questions after reviewing this document, you can submit them by sending an email to developers@anthology.com. + + \ No newline at end of file diff --git a/docs/student/best-practices/RefundAmountValidation.md b/docs/student/best-practices/RefundAmountValidation.md new file mode 100644 index 00000000..18a7ddf3 --- /dev/null +++ b/docs/student/best-practices/RefundAmountValidation.md @@ -0,0 +1,50 @@ +--- +title: "Refund API Amount Validation" +id: studentapi-refundamountvalidation-details +sidebar_position: 1 +author: Jim Burns +published: "" +edited: "" +--- + + + +A common use case for integrators is to post a refund transaction to a student's ledger card. The refund transaction can be a full payment reversal, a partial refund of a particular payment or a refund due to the student withdrawing from school. A common validation message that is returned when attempting to post this refund is "Refund amount cannot exceed #####.##". This document will provide the details on the execution logic that is generating this validation message and steps for calculating the maximum amount that is allowed to be refunded from the Anthology Student data model. Understanding this logic will allow for the necessary corrective steps/actions to be taken to properly address the validation message being returned. + +The API endpoint that is used to post an unscheduled refund is api/student-accounting/ledger-refund-transactions. This is the API where this validation message can be returned. + +## Root cause of "Refund amount cannot exceed #####.##" validation message + +Validation logic exists in Anthology Student that will not allow the net amount received for a given packaged student award to be less than 0. Additionally, the net amount received for all other payment/refund transactions that are not associated to a packaged award cannot be less than 0. Transactions not associated to a StudentAward record are grouped by the associated Academic Year Sequence. If the refund is being posted for a packaged award, then certain properties in the request must be populated. The StudentAwardId property in the request will hold the Id of the StudentAward record the refund is associated to. There is also a PaidDisbursementId property as well. If the StudentAwardId property is populated, then the PaidDisbursementId property is optional and can be used to specify the specific received disbursement that is being refunded. If a specific disbursement is referenced with the PaidDisbursementId property, then the refund amount cannot exceed the net amount received for that disbursement. + +If the refund being posted is not for a packaged award, then the StudentAwardId property will not be populated in the request. When this is the case, the validation logic will use the AcademicYearSequence provided in the request within the calculation to determine the net amount received. The net amount received calculation will include all relevant transactions that are NOT associated to a StudentAward AND have an AcademicYearSequence value that matches what is provided in the request. + +A good visual aid for how this validation logic works can be found on the Refunds tab when accessing the student's ledger card in the web client UI. Once a student record is accessed in the UI, expand Student Accounts and then select the Ledger Card tile. Then select the Refunds tab. When attempting to post a refund or schedule a refund, the validation logic on the proposed refund amount will calculate the net amount received which is "Amount Received" - ("Amount Refunded" + "Amount Scheduled" + "Stipend Amount"). The amount of the refund attempting to be posted is then subtracted from this amount. If the result is less than 0, then the validation message "Refund amount cannot exceed....." will be generated. Note that there will be one row displayed on the grid per StudentAward record that exists for the student. If there are any payment transactions on a student's ledger card that are not associated to a StudentAward record, then a row will be displayed on the grid with a Fund Source label of "Student". Also, if these payment transactions have different Academic Year sequence associations, then multiple rows will be listed -- one for each Academic Year sequence. + +![RefundAmountValidation](/assets/img/RefundAmountValidation1.png) + + +### Amount Received + +This column on the grid is the sum of all payments received for the listed fund source on the grid. As mentioned above, all rows with a fund source label of "Student" are NOT associated to a StudentAward entity record. Depending on how the AcademicYearSequence is associated to "Student" transactions, there may be 1 or more rows shown with this fund source. If there are multiple rows, then this means that there are different values for AcademicYearSequence that have been associated to the "Student" fund source transactions. + +### Amount Refunded + +This column on the grid is the sum of refunds that have been paid/processed for the listed fund source on the grid. The entity that stores this information is the Refunds entity. The amount listed will also take into account any processed refunds that have been subsequently been voided. Rows in the Refunds entity with a status of 'P' or 'V' will be included in the calculated amount for this column. + +### Amount Scheduled + +This column on the grid is the sum of refunds that are scheduled to be paid but have not yet been processed. Rows in the Refunds entity with a Status of 'N' or 'S' are included in the calculated amount for this column. + +### Stipend Amount + +This column on the grid is the sum of processed stipends as well as scheduled stipends. A processed stipend will have a row in the Refunds entity. If the row in the Refunds entity is a stipend, then there will be a value in the StipendScheduleId property. If this property is null or 0, then the row is a Refund. A stipend that is scheduled but not yet processed will reside in the StipendSchedule entity and will have a value of 'S' in the Status property. + + +## Conclusion + +If the "Refund amount cannot exceed......" validation message is received and the refund that is being posted is NOT for a packaged student award record, then the most likely cause of this error is that the AcademicYearSequence property is not being set correctly in the request. As mentioned above, the amount allowed for posting for "Student" fund sources is calculated using the AcademicYearSequence as a grouping value. So if a payment was previously posted and was associated to AcademicYearSequence of 1 but the value in the Refund API payload for AcademicYearSequence is 0, then this validation message will be returned (assuming there are no other payment transactions associated to an AcademicYearSequence of 0). + +If there are questions after reviewing this document, you can submit them by sending an email to developers@anthology.com. + + \ No newline at end of file diff --git a/static/assets/img/AccountBalances1.png b/static/assets/img/AccountBalances1.png new file mode 100644 index 00000000..6283da44 Binary files /dev/null and b/static/assets/img/AccountBalances1.png differ diff --git a/static/assets/img/AccountBalances2.png b/static/assets/img/AccountBalances2.png new file mode 100644 index 00000000..ec4df025 Binary files /dev/null and b/static/assets/img/AccountBalances2.png differ diff --git a/static/assets/img/AccountBalances3.png b/static/assets/img/AccountBalances3.png new file mode 100644 index 00000000..611027b5 Binary files /dev/null and b/static/assets/img/AccountBalances3.png differ diff --git a/static/assets/img/AccountBalances4.png b/static/assets/img/AccountBalances4.png new file mode 100644 index 00000000..fddfdaab Binary files /dev/null and b/static/assets/img/AccountBalances4.png differ diff --git a/static/assets/img/ManageClassSections1.png b/static/assets/img/ManageClassSections1.png new file mode 100644 index 00000000..69713780 Binary files /dev/null and b/static/assets/img/ManageClassSections1.png differ diff --git a/static/assets/img/ManageClassSections2.png b/static/assets/img/ManageClassSections2.png new file mode 100644 index 00000000..f7fb4118 Binary files /dev/null and b/static/assets/img/ManageClassSections2.png differ diff --git a/static/assets/img/ManageClassSections3.png b/static/assets/img/ManageClassSections3.png new file mode 100644 index 00000000..cc78b379 Binary files /dev/null and b/static/assets/img/ManageClassSections3.png differ diff --git a/static/assets/img/ManageCustomFields1.png b/static/assets/img/ManageCustomFields1.png new file mode 100644 index 00000000..c556a1a7 Binary files /dev/null and b/static/assets/img/ManageCustomFields1.png differ diff --git a/static/assets/img/ManageCustomFields2.png b/static/assets/img/ManageCustomFields2.png new file mode 100644 index 00000000..160c8859 Binary files /dev/null and b/static/assets/img/ManageCustomFields2.png differ diff --git a/static/assets/img/ManageCustomFields3.png b/static/assets/img/ManageCustomFields3.png new file mode 100644 index 00000000..0d072be7 Binary files /dev/null and b/static/assets/img/ManageCustomFields3.png differ diff --git a/static/assets/img/ManageCustomFields4.png b/static/assets/img/ManageCustomFields4.png new file mode 100644 index 00000000..ff7b58d0 Binary files /dev/null and b/static/assets/img/ManageCustomFields4.png differ diff --git a/static/assets/img/ManageCustomFields5.png b/static/assets/img/ManageCustomFields5.png new file mode 100644 index 00000000..794f330e Binary files /dev/null and b/static/assets/img/ManageCustomFields5.png differ diff --git a/static/assets/img/ManageCustomFields6.png b/static/assets/img/ManageCustomFields6.png new file mode 100644 index 00000000..ff919f00 Binary files /dev/null and b/static/assets/img/ManageCustomFields6.png differ diff --git a/static/assets/img/ManageCustomFields7.png b/static/assets/img/ManageCustomFields7.png new file mode 100644 index 00000000..a390b373 Binary files /dev/null and b/static/assets/img/ManageCustomFields7.png differ diff --git a/static/assets/img/ManageCustomFields8.png b/static/assets/img/ManageCustomFields8.png new file mode 100644 index 00000000..8210e1ee Binary files /dev/null and b/static/assets/img/ManageCustomFields8.png differ diff --git a/static/assets/img/ManageCustomFields9.png b/static/assets/img/ManageCustomFields9.png new file mode 100644 index 00000000..68fb49b7 Binary files /dev/null and b/static/assets/img/ManageCustomFields9.png differ diff --git a/static/assets/img/ManageEnrollmentAreasOfStudy1.png b/static/assets/img/ManageEnrollmentAreasOfStudy1.png new file mode 100644 index 00000000..0ccef653 Binary files /dev/null and b/static/assets/img/ManageEnrollmentAreasOfStudy1.png differ diff --git a/static/assets/img/ManageEnrollmentAreasOfStudy2.png b/static/assets/img/ManageEnrollmentAreasOfStudy2.png new file mode 100644 index 00000000..c89a2c58 Binary files /dev/null and b/static/assets/img/ManageEnrollmentAreasOfStudy2.png differ diff --git a/static/assets/img/ManageEnrollmentAreasOfStudy3.png b/static/assets/img/ManageEnrollmentAreasOfStudy3.png new file mode 100644 index 00000000..e125e9f2 Binary files /dev/null and b/static/assets/img/ManageEnrollmentAreasOfStudy3.png differ diff --git a/static/assets/img/PaymentReversalUsingAPI1.png b/static/assets/img/PaymentReversalUsingAPI1.png new file mode 100644 index 00000000..cf38a1fb Binary files /dev/null and b/static/assets/img/PaymentReversalUsingAPI1.png differ diff --git a/static/assets/img/PaymentReversalUsingAPI2.png b/static/assets/img/PaymentReversalUsingAPI2.png new file mode 100644 index 00000000..de7ecd1c Binary files /dev/null and b/static/assets/img/PaymentReversalUsingAPI2.png differ diff --git a/static/assets/img/PaymentReversalUsingAPI3.png b/static/assets/img/PaymentReversalUsingAPI3.png new file mode 100644 index 00000000..5b616611 Binary files /dev/null and b/static/assets/img/PaymentReversalUsingAPI3.png differ diff --git a/static/assets/img/PaymentReversalUsingAPI4.png b/static/assets/img/PaymentReversalUsingAPI4.png new file mode 100644 index 00000000..399aeda8 Binary files /dev/null and b/static/assets/img/PaymentReversalUsingAPI4.png differ diff --git a/static/assets/img/PaymentReversalUsingAPI5.png b/static/assets/img/PaymentReversalUsingAPI5.png new file mode 100644 index 00000000..b73e719b Binary files /dev/null and b/static/assets/img/PaymentReversalUsingAPI5.png differ diff --git a/static/assets/img/RefundAmountValidation1.png b/static/assets/img/RefundAmountValidation1.png new file mode 100644 index 00000000..02e2d5a9 Binary files /dev/null and b/static/assets/img/RefundAmountValidation1.png differ