Skip to content Skip to footer

How to set up an attendance app?

We have two types of attendance apps.
1. Auto Attendance
2. Manual Attendance
Below is the way how to set these apps for any client
There are only minor differences between the setup of auto and manual attendance, that I have listed down in this document.

Manual Attendance:

Required Forms and fields with properties to be set:

  1. User form
    Minimum fields and its properties value required to be set as below:
    1. First name
    2. last name
    3. Email id (Textbox Email type)
    Properties :
    Required: Yes
    Hidden: No
    Value Edit Mode: Editable
  2. Registration form
    Minimum fields and its properties value required to be set as below:
    1. Face scan
      Widget: verification widget
      Properties :
      Action Type : Register
      Save Photo: Yes
      On Image Capture : onImageCapture
      Required: Yes
      Hidden: No
      Value Edit Mode: Editable
    2. User
      Widget: Reference choice list
      Reference: User form
      Properties :
      Required: Yes
      Hidden: No
      Value Edit Mode: Editable
      On_value_change : onUserSelectionChange
  3. Attendance form
    Minimum fields and its properties value required to be set as below:
    1. Verify In
      Widget: Verification Widget
      Properties :
      Action Type: verify
      On Image Capture : onInImageCapture ( function name from form script for face verification API call )
      Hidden: No
      Value Edit Mode: Editable
      Unique Identifier: Verify_IN
    2. Type
      Widget: Choice List
      Choices to be set (has to be exactly the same as mentioned):
      Check In
      Check Out
      Properties :
      Required: Yes
      Hidden: No
      Value Edit Mode: Editable
      Unique Identifier: Type
    3. Timestamp in
      Widget: Timestamp
      Properties :
      Mode: on submit
      Unique Identifier : Timestamp_IN
      Hidden: yes
    4. Location IN
      Widget : GPS
      Properties:
      Mode: on_submit
      Identifier : Location_IN
    5. Verify Out
      Widget: Verification Widget
      Properties :
      Action Type: verify
      On Image Capture : onOutImageCapture (function name from form script for face verification API call)
      Hidden: Yes
      Unique Identifier: Verify_OUT
    6. Timestamp out
      Widget: Timestamp
      Properties :
      Mode: on submit
      Unique Identifier: Timestamp_OUT
    7. Location OUT
      Widget : GPS
      Properties:
      Mode: on_submit
      Identifier: Location_OUT
    8. User
      Widget: Reference choice list
      Reference Form: User
      Properties :
      Required: Yes
      Hidden: Yes
      Value Edit Mode: Editable
    9. Merged
      Widget: Toggle
      Properties :
      Default Value: No
      Hidden: Yes
    10. Duration
      Widget: Formula Widget
      Properties:
      Hidden: Yes
      Unique Identifier: Duration
      code : return Timestamp_OUT – Timestamp_IN
    11. User ID
      Widget : Textbox widget
      Properties:
      Hidden: Yes
      Unique Identifier: User_Id

Form scripts:

  1. Registration FormScript:

NOTE:

  1. The registration form script is the same for auto and manual attendance.
  2. Replace the ‘Collection Id form client’ in the below form script with the new collection id created for a specific client.
    You will need to contact the developer to get this collection id.
  3. Replace the identifiers of the ‘Face Scan’ widget and user widget in the form script.
function onImageCapture(ws) {
var scanvalue = String(ws.getWidgetValue('Face_Scan'))// change face field id
if(scanvalue != ""){
var imageJSON = JSON.parse(scanvalue);
var imagepath = imageJSON.path;
var collectionId = "Collection Id form client"; // put unique collection id
var parameterJson = [{"CollectionId":collectionId}];
var imageList = [imagepath];
ws.callAPI('https://app.axonator.com/api/v2/verifyFace/',JSON.stringify(parameterJson), JSON.stringify(imageList), "onImageScanSuccess", "onImageScanError");
}

}

function onImageScanSuccess(ws, response){
var scanvalue = String(ws.getWidgetValue('Face_Scan')) // change face field id
var responseJSON = JSON.parse(response);
if (responseJSON.hasOwnProperty('found')) {
responseJSON.CollectionId = "Collection Id form client" // put unique collection id
if (responseJSON.found) {
responseJSON.ux = {"msg":"This user is already registered", "bgcolor":"E92222", "fgcolor":"ffffff", "text":"User Already Exists"}
} else {
responseJSON.ux = {"msg":"This user will be registered when you save", "bgcolor":"68C256", "fgcolor":"ffffff", "text":"New User"}
}
} else {
responseJSON.ux = {"msg":"Error in response : " + responseJSON, "bgcolor":"ffffff", "fgcolor":"ffffff", "text":""}
}
var images = JSON.parse(scanvalue)
responseJSON.name = images.name
responseJSON.path = images.path
ws.setWidgetValue("Face_Scan",JSON.stringify(responseJSON)); // change face field id
ws.reloadUICell("Face_Scan"); // change face field id
}

function onImageScanError(ws, response){

}

function onUserSelectionChange(ws){
var scanvalue = String(ws.getWidgetValue('Face_Scan')) // change face field id
var creator = JSON.parse(ws.getWidgetValue('User')); // change user field id
var scan_resp = JSON.parse(scanvalue);
scan_resp.mfo = creator;
ws.setWidgetValue("Face_Scan",JSON.stringify(scan_resp)); // change face field id
}

function on_submit(ws){
var scanvalue = String(ws.getWidgetValue('Face_Scan')) // change face field id
var scan = JSON.parse(scanvalue);
if(scan.found){
ws.setGeneralError(JSON.stringify({"t":"User Already Exists","m":"The scanned face is already registered.","tp":"error"}));
}
}

2. Attendance FormScript

NOTE:
1. Replace the ‘Collection Id form client’ in the below form script with the new collection id created for a specific client.
You will need to contact the developer to get this collection id.
2. Changes:
a. Manual Attendance:
In formscript, “IsAutoAttendance” variable should be set false
var IsAutoAttendance = false
b. Auto Attendance:
In formscript, ‘IsAutoAttendance’ variable should be set true
var IsAutoAttendance = true

function val(ws,identifier){
  return ws.getWidgetValue(identifier);
}

function isVisible(ws,identifier){
  return ws.isWidgetVisible(identifier);
}

function reload(ws, identifiers) {
    if(typeof(identifiers)=="object")
    ws.reloadUICells(identifiers);
    else
    ws.reloadUICells([identifiers]);
}

// key is to be set true only if the form is for auto attendance
var IsAutoAttendance = true
var widget_identifier = ''

function onInImageCapture(ws) {
	widget_identifier = 'Verify_IN'
	onImageCapture(ws)
}

function onOutImageCapture(ws){
	widget_identifier = 'Verify_OUT'
	onImageCapture(ws)
}

function onImageCapture(ws) {
	var imageJSON = JSON.parse(ws.getWidgetValue(widget_identifier));
	var imagepath = imageJSON.path;
	var collectionId = "Collection Id form client"; // put unique collection id
	var parameterJson = [{"CollectionId" : collectionId, 'IsAutoAttendance': IsAutoAttendance}];
	var imageList = [imagepath];
	ws.callAPI('https://app.axonator.com/api/v2/verifyFace/',JSON.stringify(parameterJson), JSON.stringify(imageList), "onImageScanSuccess", "onImageScanError");
}

function onImageScanSuccess(ws, response){
	var responseJSON = JSON.parse(response);
	if (responseJSON.hasOwnProperty('found')) {
		responseJSON.CollectionId = "Collection Id form client" // put unique collection id
		if(responseJSON.hasOwnProperty('status') && responseJSON.status == 'failed'){
			verification_ux = {"msg":"", "bgcolor":"E92222", "fgcolor":"ffffff", "text":"No face detected."}
			type_of_submission = ''
		}else if (responseJSON.found) {
			if (!responseJSON.mFOID || responseJSON.mFOID == "[]"){
				verification_ux = {"msg":"Face is matched but no user found", "bgcolor":"E92222", "fgcolor":"ffffff", "text":"No user found"}
				type_of_submission = ''
			}
			else{
				actual_response = JSON.parse(responseJSON.mFOID)
				verification_ux = {"msg":"User Identified Successfully", "bgcolor":"008000", "fgcolor":"ffffff", "text":actual_response[0]['fot']}
				type_of_submission = JSON.stringify([actual_response[0]['type_of_submission']])
			}
		} else {
			verification_ux = {"msg":"This user is not identified", "bgcolor":"E92222", "fgcolor":"ffffff", "text":"Identification Failed"}
			type_of_submission = ''
		}
		user_data = responseJSON.mFOID
	} else {
		verification_ux = {"msg":"Error in response : " + responseJSON, "bgcolor":"ffffff", "fgcolor":"ffffff", "text":""}
		type_of_submission = ''
		user_data = ''
	}
	var images = JSON.parse(ws.getWidgetValue(widget_identifier))
	responseJSON.name = images.name
	responseJSON.path = images.path
	responseJSON.ux = verification_ux
	ws.setWidgetValue("User_2", user_data) 
	ws.setWidgetValue(widget_identifier,JSON.stringify(responseJSON))

	// if this is auto attendance the type and Verify_OUT will be set automatically
	if(IsAutoAttendance){
		if (type_of_submission == '["Your attendance is already recorded"]'){
			ws.setWidgetValue('Type','');
			ws.setWidgetValue(widget_identifier,'')
			// ws.showAlert(JSON.stringify({"t":"Can not submit","m":'Your attendance is already recorded'}))
		}
		else if(type_of_submission != ''){
			ws.setWidgetValue('Type',type_of_submission);
			ws.validateAndSubmit();
		}
	}

	reload(ws,["Verify_IN","Type"])
}

function onImageScanError(ws, response){
	ws.showAlert(JSON.stringify({"t":"In error","m":response}))
}

function oninimagechange(ws){
    var scanvalue = String(ws.getWidgetValue('Verify_IN'))
    if (scanvalue)
        {
        if(JSON.parse(scanvalue).status == 'failed'){
            ws.showAlert(JSON.stringify({"t":"No face detected.","m":"Please make sure your face is clear and close enough to the camera while scanning your face."}))
        }
    }
}

// function onoutimagechange(ws){
//     var scanvalue = String(ws.getWidgetValue('Verify_OUT'))
//     if (scanvalue)
//         {
//         if(JSON.parse(scanvalue).status == 'failed'){
//             ws.showAlert(JSON.stringify({"t":"No face detected.","m":"Please make sure your face is clear and close enough to the camera while scanning your face."}))
//         }
//     }
// }

function on_submit(ws){
	if (ws.getWidgetValue('Type') == '["Check Out"]'){
		ws.setWidgetValue("Verify_IN",'');

		// validation if face not scanned
		var scanvalueout = String(ws.getWidgetValue('Verify_OUT'))
		if(scanvalueout == ""){
			ws.setGeneralError(JSON.stringify({"t":"Face Not Scanned","m":"Please Scan Face to Mark Attendance","tp":"error"}));
		}
		else{
			var scan = JSON.parse(scanvalueout);
		}

	}else{
		ws.setWidgetValue("Verify_OUT",'');

		// validation if face not scanned
		var scanvaluein = String(ws.getWidgetValue('Verify_IN'))
		if(scanvaluein == ""){
			ws.setGeneralError(JSON.stringify({"t":"Face Not Scanned","m":"Please Scan Face to Mark Attendance","tp":"error"}));
		}
		else{
			var scan = JSON.parse(scanvaluein);
		}
	}

	if(scan != null && scan.hasOwnProperty('status') && scan.status == 'failed'){
    	ws.setGeneralError(JSON.stringify({"t":"No face detected.","m":"Please make sure your face is clear and close enough to the camera while scanning your face.","tp":"error"}));
	}else if(scan == null || !scan.found){
		ws.setGeneralError(JSON.stringify({"t":"User not found.","m":"The user is not identified. Please confirm that the user registration is done.","tp":"error"}));
    }else if(scan != null && !scan.mFOID || scan.mFOID == "[]"){
		ws.setGeneralError(JSON.stringify({"t":"Face matched but no user found.","m":"User not found.","tp":"error"}));
	}
	else{
		var type = JSON.parse(val(ws,"Type"));
		if(type[0] == 'Check In'){
			if (ws.androidCheckAndDozePermission()) {
				ws.startLiveTracking();
			} else {
				ws.setGeneralError(JSON.stringify({"t":"Permission.","m":"Please allow permission, then submit the form.","tp":"error"}));
			}
		}
		else if(type[0] == 'Check Out'){
			ws.stopLiveTracking();
		}
	}
}

Required AppVersion Manifest Keys


NOTE: Put all these keys with correct values in the app version manifest.

  1. “advance_user”:1 (Required to show the attendance view on the Users tab in the app)
  2. “attendance_form”:12345 (To identify attendance form)
  3. “attendance_merge_field_id”: user (used this id in the code for merging check in and check out records, export, etc.)
  4. “user_identifier”: user_1 (To identify the user in attendance form)
  5. “out_time”: “15:30:00” (Required for auto check out if the client did not submit the check out data in a day. By default set to 9 PM in UTC. change according to the client’s requirement
  6. “user_email_field_id”: Email
  7. “user_form_id”: 12345 (To identify user form)
  8. “user_id”:”86534_User_Id” (user-id field identifier form attendance form with attendance form id.)
  9. “registration_form”:12345 (To identify registration form)
  10. “collection_id_keys”: [
    “face_verification_collections”
    ]
  11. “face_verification_collections”: [
    “Collection ID of the client”
    ]

The 10th and 11th keys are used to create the collection with the mentioned collection name and clear the faces from the collection on Clear data.

So After placing all the values in right place the JSON will look like this:
This is an example JSON.
{
“advance_user”:1,
“attendance_form”:1234,
“registration_form”:86529,
“attendance_merge_field_id” : “User_2”,
“user_identifier” : “User”,
“out_time”:”15:30:00″,
“user_email_field_id”: “Email ID”,
“user_form_id”:12345,
“user_id”:”86534_User_Id”,
“replace”:[
{
“data”:”name”,
“name”:”343368_User_2_name”
},
{
“data”:”in”,
“name”:”343368_Timestamp_IN”
},
{
“data”:”out”,
“name”:”343368_Timestamp_OUT”
},
{
“data”:”duration”,
“name”:”343368_Duration”
},
{
“data”:”id”,
“name”:”343368_User_Id”
},
{
“data”:”title”,
“name”:”343371_FullName”
},
{
“data”:”subtitle”,
“name”:”343371_Email”
},
{
“data”:”user_id”,
“name”:”343368_User_2″
},
{
“data”:”foid”,
“name”:”form_object_id”
}
],
“collection_id_keys”: [
“face_verification_collections”
],
“face_verification_collections”: [
“Collection ID of the client”
]
}

Auto Attendance:

( Add key “auto_detect”: 1 to the Verification widget JSON object from the Attendance form using Django admin)

Required Forms and fields with properties to be set:

  1. For auto attendance setup, the fields required are the same as manual attendance.
  2. The only difference is in the attendance form in the field ‘Type’ widget.
  3. So the type widget in the attendance form in auto attendance will be like this

Type
Widget: Choice List
Choices to be set (has to be exactly the same as mentioned) :
Check In
Check Out
Properties :
Required: Yes
Hidden: Yes
Unique Identifier: Type

4. Change the Verify IN field name to Verify and make it visible i.e Hidden = No

Custom Forms

  1. Weekly off form

Minimum fields and its properties value required to be set as below:

  1. Weekly Off Date
    Widget: Date Time widget
    Properties :
    Date Picker Type: Date Range
    Required: Yes
  2. User
    Widget: Reference choice list
    Reference: User form
    Properties :
    Required: Yes

2. Holiday Form

Minimum fields and its properties value required to be set as below:

1. Name
Widget: Text Box

  1. Dates
    Widget: Date Time widget
    Properties :
    Date Picker Type: Date Range
    Required: Yes

3. Leave Form

Minimum fields and its properties value required to be set as below:

  1. Date
    Widget: Date Time widget
    Properties :
    Date Picker Type: Date Range
    Required: Yes
  2. User
    Widget: Reference choice list
    Reference: User form
    Properties :
    Required: Yes
  3. Type
    Widget: Fixed choice list
    Choices:
    Earned Leave or Privilege Leave
    Casual Leave
    Sick Leave or Medical Leave
    Maternity Leave
    Half Pay Leave
    Quarantine Leave
    Study Leave or Sabbatical Leave
    Other
  4. Other
    Widget:text box
    Properties:-
    Multiline: Yes
    Put Visibility if other
  5. Approved
    Widget: Toggle
    Properties:-Default (NO)

Add the below keys to the App manifest after adding the above custom forms-

  1. “LEAVE_FORM”:”86319″ (Leave form id)
  2. “LEAVE_FORM_USER”:”86319_User_2″ (User field identifier from the Leave form)
  3. “LEAVE_DATE”:”86319_Dates_2″ (Dates field identifier from Leave form)
  4. “LEAVE_APPROVED”: “86319_Approved” (Approved field identifier from Leave form)
  5. “HOLIDAY_FORM”:”86316″ (Holiday form id)
  6. “HOLIDAY_DATE”:”86316_Dates” (Dates field identifier from Holiday form)
  7. “WEEKLY_OFF”:[Saturday, Sunday] (Mention weekly off days)
  8. “WEEKLY_OFF_FORM”: “163790” (Weekly Off form id)
  9. “WEEKLY_OFF_DATE”: “163790_Date” (Dates field identifier from Weekly off form)
  10. “WEEKLY_OFF_USER”: “163790_User_4” (User field identifier from Weekly off form)

Was This Article Helpful?

0
0 Comments

There are no comments yet

Leave a comment

Your email address will not be published. Required fields are marked *

Close Bitnami banner
Bitnami