# Workforce (checkin)
## Location
### location.query
#### Request
```json=
{
skip: 0,
limit: 20
}
```
#### Response
```json=
{
"id": 1,
"p": [
null,
[
{
"_id": "601b82f9a201fa0f9328f553",
"title": "Whizdom",
"address": {
"name": "Whizdom condo",
"addr": "Soi 101/1",
"city": "Bang Chak",
"state": "BKK",
"loc": [
100.613065323153,
13.6866564985291
]
},
"timezone": "Asia/Bangkok",
"nid": "519909e80d7735ab7c000002",
"uid": "5cff67cbf8efedccbfc005b3",
"status": "active"
},
{
"_id": "601b82bda201fa0f9328f3a9",
"title": "True Digital Park",
"address": {
"name": "TDPK",
"addr": "Sukhumvit Rd",
"city": "Bang Chak",
"state": "BKK",
"loc": [
100.6099974,
13.68528
]
},
"timezone": "Asia/Bangkok",
"nid": "519909e80d7735ab7c000002",
"uid": "5cff67cbf8efedccbfc005b3",
"status": "active"
},
{
"_id": "6007dc0bbf1f14aefcbecc38",
"title": "Home",
"address": {
"name": "Home Kanlapaphurk",
"addr": "Srinakarin Rd",
"city": "Bangna",
"state": "New York",
"loc": [
100.653586,
13.640117
]
},
"timezone": "Asia/Bangkok",
"nid": "519909e80d7735ab7c000002",
"uid": "5cff67cbf8efedccbfc005b3",
"status": "active"
}
]
]
}
```
### location.search
#### Request
| params | type | description | example | required |
| ------- | ------ | ------------------ | ---------------------------- | -------- |
| search | Object | text and location | { q: 'true', loc: [-70, 40]} | Y |
| options | Object | pagination options | { skip:0, limit: 10} | N |
#### Response
```json=
{
"id": 1,
"p": [
{
"locations": [
{
"title": "Home",
"address": {
"name": "Home Kanlapaphurk",
"city": "Bangna",
"state": "New York",
"loc": [
100.653586,
13.640117
]
},
"timezone": "Asia/Bangkok",
"nid": "519909e80d7735ab7c000002",
"uid": "5cff67cbf8efedccbfc005b3",
"status": "active",
"_id": "6007dc0bbf1f14aefcbecc38"
}
]
}
]
}
```
### location.getNearLocations
#### Request
| params | type | description | example | required |
|---------- |------- |-------------------- |------------ |--------------------- |
| lng | Float | longitude | 100.653586 | Y |
| lat | Float | latitude | 13.640117 | Y |
| distance | Int | distance by meter | | N (default is 2000) |
#### Response
```json=
{
"id": 1,
"p": [
{
"locations": [
{
"_id": "6007dc0bbf1f14aefcbecc38",
"title": "Home",
"address": {
"name": "Home Kanlapaphurk",
"city": "Bangna",
"state": "New York",
"loc": [
100.653586,
13.640117
]
},
"timezone": "Asia/Bangkok",
"nid": "519909e80d7735ab7c000002",
"uid": "5cff67cbf8efedccbfc005b3",
"status": "active"
}
]
}
]
}
```
## Checkin
> All of these (checkin, update, checkout) got the same data structure for the request params and response data.
*REMARK ENUM*
`['LOCATION_NOT_FOUND', 'OUT_OF_RANGE', 'IN_RANGE']`
### checkin.checkIn
#### Request (Office)
```json=
{
"location":{
"name":"TDPK",
"addr":"101/1 Sukhumvit Rd.",
"latitude":13.640112,
"longitude":100.653587
},
"description":"test",
"locationId":"6007dc0bbf1f14aefcbecc38",
"remark":"IN_RANGE"
}
```
#### Response (Office)
```json=
{
"id": 1,
"p": [
null,
{
"__v": 0,
"updatedAt": "2021-02-03T06:45:18.923Z",
"createdAt": "2021-02-03T06:45:18.923Z",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"location": {
"latitude": 13,
"longitude": 100
},
"description": "test",
"deviceId": "curl",
"action": "check-in",
"locationId": "6007dc0bbf1f14aefcbecc38",
"sessionId": "VX3ljr45tK",
"_id": "601a467eb56efe4f98233ba9"
}
]
}
```
#### Request (Offsite)
```json=
{
"location":{
"name":"TDPK",
"addr":"101/1 Sukhumvit Rd.",
"latitude":13.640112,
"longitude":100.653587
},
"description":"test",
"offsiteLocation":{
"name":"Panin",
"addr":"Sukhumvit Rd.",
"latitude":13.640100,
"longitude":100.653583
},
"remark":"OUT_OF_RANGE"
}
```
#### Response (Offsite)
```json=
{
"id": 1,
"p": [
null,
{
"__v": 0,
"updatedAt": "2021-02-10T07:33:42.871Z",
"createdAt": "2021-02-10T07:33:42.871Z",
"location": {
"name": "TDPK",
"addr": "101/1 Sukhumvit Rd.",
"latitude": 13,
"longitude": 100
},
"description": "test",
"offsiteLocation": {
"name": "Panin",
"addr": "Sukhumvit Rd.",
"latitude": 13,
"longitude": 100
},
"remark": "OUT_OF_RANGE",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"deviceId": "curl",
"action": "update",
"sessionId": "CiKgIkdrnJ",
"_id": "60238c56fab60cd87d50be0d"
}
]
}
```
#### Response(error) duplicate checkin, code: **10000**
```json=
{
"id": 1,
"p": [
"{\"isEko\":true,\"name\":\"CheckInCannotCheckInError\",\"refData\":{},\"code\":400,\"message\":\"Duplicate check in.\",\"ekoCode\":100000}"
]
}
```
### checkin.updateLocation
#### Request
```json=
{
"location":{
"name":"TDPK",
"addr":"101/1 Sukhumvit Rd.",
"latitude":13.640112,
"longitude":100.653587
},
"description":"test",
"locationId":"6007dc0bbf1f14aefcbecc38",
"remark":"IN_RANGE"
}
```
#### Response
```json=
{
"id": 1,
"p": [
null,
{
"__v": 0,
"updatedAt": "2021-02-04T07:01:36.547Z",
"createdAt": "2021-02-04T07:01:36.547Z",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"location": {
"latitude": 13,
"longitude": 100
},
"description": "test",
"deviceId": "curl",
"action": "update",
"sessionId": "VX3ljr45tK",
"locationId": "6007dc0bbf1f14aefcbecc38",
"_id": "601b9bd063c6e3569f0387a4"
}
]
}
```
#### Response (error) - update location without checkin history
```json=
{
"id": 1,
"p": [
"{\"isEko\":true,\"name\":\"CheckInCannotUpdateError\",\"refData\":{},\"code\":400,\"message\":\"You must checkin first in order to update location.\",\"ekoCode\":100002}"
]
}
```
### checkin.checkOut
#### Request
```json=
{
"location":{
"name":"TDPK",
"addr":"101/1 Sukhumvit Rd.",
"latitude":13.640112,
"longitude":100.653587
},
"description":"test",
"locationId":"6007dc0bbf1f14aefcbecc38",
"remark":"IN_RANGE"
}
```
#### Response
```json=
{
"id": 1,
"p": [
null,
{
"__v": 0,
"updatedAt": "2021-02-04T07:04:24.999Z",
"createdAt": "2021-02-04T07:04:24.999Z",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"location": {
"name": "TDPK",
"addr": "101/1 Sukhumvit Rd.",
"latitude": 13,
"longitude": 100
},
"description": "test",
"deviceId": "curl",
"action": "check-out",
"sessionId": "VX3ljr45tK",
"locationId": "6007dc0bbf1f14aefcbecc38",
"_id": "601b9c7863c6e3f8290387a5"
}
]
}
```
#### Response(error) - checkOut with no checkIn history
```json=
{
"id": 1,
"p": [
"{\"isEko\":true,\"name\":\"CheckInCannotCheckOutError\",\"refData\":{},\"code\":400,\"message\":\"You must checkin first in order to checkout.\",\"ekoCode\":100001}"
]
}
```
### checkin.querySession
#### Request - on tab page with no sessionId
will return the latest log back along with the sessionId
#### Response
```json=
{
"id": 1,
"p": [
null,
{
"_id": "601b9c7863c6e3f8290387a5",
"updatedAt": "2021-02-04T07:04:24.999Z",
"createdAt": "2021-02-04T07:04:24.999Z",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"location": {
"name": "TDPK",
"addr": "101/1 Sukhumvit Rd.",
"latitude": 13,
"longitude": 100
},
"description": "test",
"deviceId": "curl",
"action": "check-out",
"sessionId": "VX3ljr45tK",
"locationId": "6007dc0bbf1f14aefcbecc38",
"__v": 0
}
]
}
```
#### Request - with sessionId (support pagination)
```json=
{
"sessionId": "VX3ljr45tK"
"skip": 0, // default 0
"limit": 20 // default 20
}
```
#### Response
```json=
{
"id": 1,
"p": [
null,
[
{
"_id": "601b9c7863c6e3f8290387a5",
"updatedAt": "2021-02-04T07:04:24.999Z",
"createdAt": "2021-02-04T07:04:24.999Z",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"location": {
"name": "TDPK",
"addr": "101/1 Sukhumvit Rd.",
"latitude": 13,
"longitude": 100
},
"description": "test",
"deviceId": "curl",
"action": "check-out",
"sessionId": "VX3ljr45tK",
"locationId": "6007dc0bbf1f14aefcbecc38",
"__v": 0
},
{
"_id": "601b9bd063c6e3569f0387a4",
"updatedAt": "2021-02-04T07:01:36.547Z",
"createdAt": "2021-02-04T07:01:36.547Z",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"location": {
"latitude": 13,
"longitude": 100
},
"description": "test",
"deviceId": "curl",
"action": "update",
"sessionId": "VX3ljr45tK",
"locationId": "6007dc0bbf1f14aefcbecc38",
"__v": 0
},
{
"_id": "601a467eb56efe4f98233ba9",
"updatedAt": "2021-02-03T06:45:18.923Z",
"createdAt": "2021-02-03T06:45:18.923Z",
"userId": "5cff67cbf8efedccbfc005b3",
"networkId": "519909e80d7735ab7c000002",
"location": {
"latitude": 13,
"longitude": 100
},
"description": "test",
"deviceId": "curl",
"action": "check-in",
"locationId": "6007dc0bbf1f14aefcbecc38",
"sessionId": "VX3ljr45tK",
"__v": 0
}
]
]
}
```
### v1/checkin.getManagers
return direct-report users with checkin last activity.
#### Request
```json=
{
skip: 0, // default 0
limit: 20, // default 20
}
```
#### Response
```json=
{
"id": 1,
"p": [
null,
[
{
"_id": "5dd37e6624bf7e01647641e9",
"avatar": "",
"coverPhoto": "",
"username": "bastest1",
"email": "bastest1@mail.com",
"firstname": "bastest1",
"lastname": "bastest1",
"position": "backend",
"status": "",
"nid": "519909e80d7735ab7c000002",
"firstLogin": "2019-11-19T05:32:39.127Z",
"lastActivity": "2019-11-19T07:04:20.033Z",
"useLocalAuthentication": true,
"hasAcceptedLegalAgreement": false,
"isBot": false,
"redeemedPoints": 0,
"totalPoints": 0,
"notificationSettings": null,
"suspendedTill": null,
"is_licensed": true,
"deleted": false,
"tags": [],
"network_admin": false,
"loginCount": 1,
"contactSortingKey": "bastest1bastest1",
"contact_index": "B"
},
]
]
}
```
### v1/checkin.getDirectReports
return direct-report users with checkin last activity.
#### Request
```json=
{
skip: 0, // default 0
limit: 20, // default 20
}
```
#### Response
```json=
// got data
{
"_id": "5cff67cbf8efedccbfc005b3",
"avatar": "",
"username": "bastest",
"firstname": "bastest",
"lastname": "bastest",
"position": "",
"checkinLog": {
"action": "check-in",
"timestamp": "2021-03-29T06:27:17.672Z"
}
},
// no data
// `checkinLog` will return null
{
"_id": "602c9f868339497768015bb0",
"avatar": "",
"username": "ch2",
"firstname": "ch2",
"lastname": "Standard",
"position": "",
"checkinLog": null
}
```
# Model Schema
checkinlogs
```javascript=
const Mongoose = require('mongoose');
module.exports = ({ db, services }) => {
// Nested Location for report and aggregate purpose
const CheckInLogsLocationSchema = new Mongoose.Schema({
_id: { type: Mongoose.Schema.ObjectId },
latitude: { type: Number },
longitude: { type: Number },
name: { type: String, trim: true },
addr: { type: String, trim: true },
radius: { type: Number },
}, { _id: false });
const CheckInLogsSchema = new Mongoose.Schema({
userId: { type: Mongoose.Schema.Types.ObjectId, required: true },
networkId: { type: Mongoose.Schema.Types.ObjectId, required: true },
location: { type: CheckInLogsLocationSchema },
action: { type: String, enum: ['check-in', 'check-out', 'update'], required: true },
description: { type: String, trim: true },
deviceId: { type: String, trim: true },
sessionId: { type: String },
remark: { type: String, enum: ['LOCATION_NOT_FOUND', 'OUT_OF_RANGE', 'IN_RANGE', 'VIA_API'] },
selectLocation: { type: CheckInLogsLocationSchema },
},
{
timestamps: true,
});
CheckInLogsSchema.index({ userId: 1, networkId: 1 });
CheckInLogsSchema.index({ userId: 1, sessionId: 1, createdAt: 1 });
return CheckInLogsSchema;
};
```
# Error
```json=
{
"CHECKIN": {
"CANNOT_CHECKIN": 100000,
"CANNOT_CHECKOUT": 100001,
"CANNOT_UPDATE": 100002,
"CANNOT_CREATE": 100003
}
}
```
## temp
```
/eko checkin.checkIn { "location":{ "name":"TDPK", "addr":"101/1 Sukhumvit Rd.", "latitude":13.640112, "longitude":100.653587 }, "description":"test", "selectLocation":{ "name":"Panin", "addr":"Sukhumvit Rd.", "latitude":13.640100, "longitude":100.653583 }, "remark":"OUT_OF_RANGE" }
/eko checkin.checkOut { "location":{ "name":"TDPK", "addr":"101/1 Sukhumvit Rd.", "latitude":13.640112, "longitude":100.653587 }, "description":"test", "selectLocation":{ "name":"Panin", "addr":"Sukhumvit Rd.", "latitude":13.640100, "longitude":100.653583 }, "remark":"OUT_OF_RANGE" }
```