SIMS 7 - Attendance (Session) Code Walkthrough
Introduction
This application is designed to show the principles of coding against SIMS Partner Interfaces. The UI is designed to facilitate the demo rather than to suggest good UI practice. The interfaces, particularly with regard to XML are simply sufficient to show principle rather than elegance.
Login
An understanding of SIMS Logins is assumed from the SIMS Write Back Core Module.
//Pick a date time as appropriate, for example:
DateTime attendanceDate;
AttendanceDate = Datetime.Now;
//Pick an Attendance Session
//Decide morning or afternoon, for example:
String Session = “PM”;
If (Morning())
Session = “AM”;
//Load the set of Attendance Codes
SIMS.Processes.TPAttendanceRead ATR = new SIMS.Processes.TPAttendanceRead();
// XML Document needed to get the codes
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
// This is the actual call to get the codes
doc.InnerXml = ATR.GetXmlAttendanceCodes();
All that remains is to extract the codes from the xml structure.
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<AttendanceCodes>
<AttendanceCode>
<AttendanceCodeID>27</AttendanceCodeID>
<Code>-</Code>
<Description>All should attend / No mark recorded</Description>
<PhysicalMappingID>5</PhysicalMappingID>
<PhysicalMappingDescription>No mark for session</PhysicalMappingDescription>
<StatisticalMappingID>6</StatisticalMappingID>
<StatisticalMappingDescription>No mark</StatisticalMappingDescription>
</AttendanceCode>
<AttendanceCode>
<AttendanceCodeID>24</AttendanceCodeID>
<Code>X</Code>
<Description> DfES X: Non-compulsory school age absence</Description>
<PhysicalMappingID>3</PhysicalMappingID>
<PhysicalMappingDescription>Out for whole session</PhysicalMappingDescription>
<StatisticalMappingID>5</StatisticalMappingID>
<StatisticalMappingDescription>Attendance not required</StatisticalMappingDescription>
</AttendanceCode>
</AttendanceCodes>
Loading the set of registration groups
SIMS.Processes.TPGroupManagement
tpgm = new SIMS.Processes.TPGroupManagement();
// We need to have an XML Doc for the call
System.Xml.XmlDocument
doc = new System.Xml.XmlDocument();
// Get the set of reg groups
doc.InnerXml = tpgm.GetXmlGroups(attendanceDate, "RegGrp");
All that then remains is to extract the groups from the XML.
<?xml version="1.0" encoding="iso-8859-1"standalone="yes"?>
<Groups>
<Group>
<BaseGroupID>381</BaseGroupID>
<BaseGroupTypeID>22</BaseGroupTypeID>
<Code>J</Code>
<Description>J</Description>
<ShortName>J</ShortName>
<PromoteToGroupID>381</PromoteToGroupID>
<StartDate />
<EndDate />
<IsActive>A</IsActive>
</Group>
</Groups>
Loading the Students in the registration Group
SIMS.Processes.TPGroupManagement
tpgm = new SI MS.Processes.TPGroupManagement();
// We need an Xml document for the call
System.Xml.XmlDocument
doc = new System.Xml.XmlDocument();
string group2get = "381"; // Base Group ID from the above
// Create the xml message to request all the students in the group
System.Xml.XmlDocument group2getXML = new System.Xml.XmlDocument();
group2getXML.InnerXml = "<BaseGroups><BaseGroupID>"+ group2get + "</BaseGroupID></BaseGroups>";
// Call Get memberships to return the
student ids.
doc.InnerXml = tpgm.GetXmlMemberships(attendanceDate,group2getXML);
This one is a little more difficult because we need to form an XML query for the required base group. The attendance date should be used to return group members for the correct date.
This returns a set of members
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<Memberships>
<Membership>
<BaseGroupID>387</BaseGroupID>
<PersonD>6347</PersonD>
<StartDate>2007-09-03T00:00:00</StartDate>
<EndDate>2008-09-01T23:59:00</EndDate> </Membership>
<Membership>
<BaseGroupID>387</BaseGroupID>
<PersonD>6355</PersonD>
<StartDate>2007-09-03T00:00:00</StartDate>
<EndDate>2008-09-01T23:59:00</EndDate>
</Membership>
</Memberships>
Translating Student Id’s into something we can display
// Call the GetXmlStudents method to load the student.
SIMS.Processes.TPPersonStudent tpps = new SIMS.Processes.TPPersonStudent();
// We need an XmlDocument for later parsing
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.InnerXml = tpps.GetXmlStudents(studentID);
This call gets the basic student information for the student whose id is ‘StudentID’ as follows:
<StudentExtendeds>
<Student>
<PersonID>2447</PersonID>
<Forename>Ben</Forename>
<Surname>Abbot</Surname>
<ChosenName />
<MiddleName />
<LegalSurname>Abbot</LegalSurname>
<Gender>Male</Gender>
<GenderID>0</GenderID>
<DOB>1986-01-17T00:00:00</DOB>
<BirthCertificateSeen>F</BirthCertificateSeen>
<AttendanceMode>All Day</AttendanceMode>
<AttendanceModeID>-1</AttendanceModeID>
<FormerUPN />
<UniqueLearnerNumber />
<YearTaughtIn />
<YearTaughtInID />
<EmergencyConsent>F</EmergencyConsent>
<NHSNumber />
<BloodGroup />
<EthnicDataSource>Provided by the parent</EthnicDataSource>
<EthnicDataSourceID>2019</EthnicDataSourceID>
<HomeLanguage>English</HomeLanguage>
<HomeLanguageID>366</HomeLanguageID>
<FirstLanguage>English</FirstLanguage>
<FirstLanguageID>2027</FirstLanguageID>
<EnglishAdditionalLanguage />
<EnglishAdditionalLanguageID />
<NationalIdentity />
<NationalIdentityID />
<AdmissionNumber>001511</AdmissionNumber>
<UPN>U820432190122</UPN>
<Religion>Christian*</Religion>
<ReligionID>339</ReligionID>
<RegGroup />
<RegGroupID />
<YearGroup />
<YearGroupID />
<House />
<HouseID />
<RollMode>Single Registration</RollMode>
<RollModeID>2</RollModeID>
<AdmissionDate>1997-09-03T00:00:00</AdmissionDate>
<DateOfLeaving>2004-07-23T23:59:00</DateOfLeaving>
<ParentalSalutation>Mr F and Mrs R Abbot</ParentalSalutation>
</Student>
</StudentExtendeds>
Please note that the SIMS user invoking the call must have access to all of the data returned by the call for it to be successful.
It is then just a case of parsing the XML to get the name information. (We already have the group information). Partners may consider adding the Admission Number to the name to enable correct identification in areas of significant duplication of names.
Recording an attendance mark
We now have:
- An attendance date
- An attendance session (AM/PM)
- A validatable mark
- A student id (or a set thereof)
DateTime lDate = DateTime.Now; // Attendance Date
string lSession = "AM"; // AM/PM
string lCode = "X"; // Mark to save
int lStudentId = 2447; //
string saveIt = "<SessionAttendances>";
saveIt += formatAttendanceMark(lDate, lSession, lStudentId, lCode);
// Add the end tag
saveIt += "</SessionAttendances>";
// Fire of the new tpbo to save the marks.
SIMS.Processes.TPAttendanceWrite tpaw = new SIMS.Processes.TPAttendanceWrite();
tpaw.WriteSessionAttendances(saveIt);
Ironically the hardest part is formatting the Attendance Mark XML for the save and hence the function below:
/// <summary>
/// The new third party business object to save session attendance marks requires
/// the creation of a string of formatted XML.
/// The outer Tag is
/// <SessionAttendances>
/// </SessionAttendances>
/// and there should be one or more instances of <SessionAttendance> </SessionAttendance>
/// formatted as below.
/// </summary>
/// <param name="date"></param>
/// <param name="session"></param>
/// <param name="person_id"></param>
/// <param name="mark"></param>
/// <returns></returns>
private string formatAttendanceMark(DateTime date, string session, int person_id, string mark)
{
StringBuilder element = new StringBuilder();
element.Append("<SessionAttendance><PersonID>");
element.Append(person_id);
element.Append("</PersonID><AttendanceDate>");
element.Append(date.Year.ToString());
element.Append("-");
string month = date.Month.ToString();
element.Append(month.Length == 1 ? "0" + month : month);
element.Append("-");
string day = date.Day.ToString();
element.Append(day.Length == 1 ? "0" + day : day);
element.Append("</AttendanceDate><SessionName>");
element.Append(session);
element.Append("</SessionName><AttendanceMark>");
element.Append(mark);
element.Append("<Comments>Added by Andys Demo App</Comments>");
if (!string.IsNullOrEmpty(minsLate))
{
element.AppendFormat("<MinsLate>{0}</MinsLate>", minsLate);
}
element.Append("</AttendanceMark></SessionAttendance>");
return element.ToString();
}
It was less than obvious when earlier versions failed because of dates formatted differently!
Handling Errors
// See of there were errors or not.
SIMS.Entities.ValidationErrors errors = tpaw.ValidationMessages;
// Create a displayable
StringBuilder mess = new StringBuilder();
bool errorsExist = false; // Marker for errors
foreach (SIMS.Entities.ValidationError err in errors)
{
errorsExist = true;
mess.Append(err.Message +"\r\n");
}
// Display the messages
if (errorsExist)
{
MessageBox.Show(mess.ToString(), "Errors Exist");
}
It is easy to assume that all saves will succeed, however any errors can be identified using the above code.
It is less easy to bubble the errors up to those responsible for entering the data if the data is synchronised when the user is ‘off line’. In this type of scheduled system, it becomes critical to ensure that the validation is as good as possible to minimise problems.
Conclusion
It is relatively simple to record session attendance marks. However, data extracted for later update may find that marks have been updated in SIMS. There is also the concept of conflicting marks, these however typically should only be applicable to lesson attendance because the last write for a mark from a partner system should prevail.