Files
duty-schedule-api/app/Controllers/Http/EmployeesController.ts

193 lines
5.3 KiB
TypeScript

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Employee from 'App/Models/Employee'
import UpdateEmployeeValidator from 'App/Validators/UpdateEmployeeValidator'
import CreateEmployeeValidator from 'App/Validators/CreateEmployeeValidator'
import Database from '@ioc:Adonis/Lucid/Database'
type ResultShow = {
id: number,
firstName: string,
lastName: string | undefined,
shorthand: string,
phone: string | undefined,
mobile: string | undefined,
email: string | undefined,
contractHours: number | undefined,
username: string | undefined,
role: string,
isActive: boolean
}
export default class EmployeesController {
public async index ({bouncer, request}: HttpContextContract) {
await bouncer.authorize('employees.index')
const limit: number = request.qs().limit ?? 10
const page: number = request.qs().page ?? 1
const select: string[] = await this.select(request.qs().select ?? '')
const sortBy = await this.sortBy(request.qs().sort_by)
const simpleSearch = await this.simpleSearch(request.qs().simple_search)
const employees = Database.query()
employees.from('employees')
employees.select(select)
if(simpleSearch) {
simpleSearch.columns.forEach(column => {
employees.orWhere(column, 'like', `%${simpleSearch.query}%`)
})
}
employees.orderBy(sortBy)
return employees.paginate(page, limit)
}
public async store ({request}: HttpContextContract) {
try {
const payload = await request.validate(CreateEmployeeValidator)
return await Employee.create({
firstName: payload.firstName,
lastName: payload.lastName,
shorthand: payload.shorthand,
email: payload.email,
phone: payload.phone,
mobile: payload.mobile,
contractHours: payload.contractHours,
username: payload.username,
password: payload.password,
role: payload.role,
isActive: payload.isActive
})
} catch (error) {
return error
}
}
public async show ({params, bouncer, auth}: HttpContextContract) : Promise<ResultShow> {
let emp: Employee
if(params.id === 'me' && auth.isLoggedIn && auth.user !== undefined){
emp = auth.user
}
else {
emp = await Employee.findOrFail(params.id)
}
await bouncer.authorize('employees.show', emp)
return {
id: emp.id,
firstName: emp.firstName,
lastName: emp.lastName,
shorthand: emp.shorthand,
phone: emp.phone,
mobile: emp.mobile,
email: emp.email,
contractHours: emp.contractHours,
role: emp.role,
username: emp.username,
isActive: emp.isActive
}
}
public async update ({params, bouncer, response, request}: HttpContextContract) {
const employee : Employee = await Employee.findOrFail(params.id)
const editContractHours : boolean = employee.contractHours !== request.input('contractHours')
await bouncer.authorize('employees.update', editContractHours, employee)
const payload = await request.validate(UpdateEmployeeValidator)
if (editContractHours){
employee.contractHours = payload.contractHours ?? 0
}
employee.firstName = payload.firstName
employee.lastName = payload.lastName ?? ''
employee.shorthand = payload.shorthand
employee.email = payload.email ?? ''
employee.phone = payload.phone ?? ''
employee.mobile = payload.mobile ?? ''
employee.isActive = payload.isActive ?? false
if (payload.username !== undefined && payload.password !== undefined ) {
employee.username = payload.username
employee.password = payload.password
}
await employee.save()
return response.ok({
status: 200,
message: "Employee updated successfully"
})
}
public async destroy ({params, bouncer}: HttpContextContract) {
await bouncer.authorize('employees.destroy')
return await Database.from('employees').where('id', params.id).delete()
}
private async sortBy(qs: string): Promise<{column : string, order?: 'asc' | 'desc' | undefined}[]> {
const regex : RegExp = /(asc|desc)\((\w+)\)/gi
const client = Database.connection()
let result: {
column: string,
order?: 'asc' | 'desc' | undefined
}[] = []
const columns = await client.columnsInfo('employees')
const match = qs?.matchAll(regex) ?? []
for (const item of match) {
if( columns.hasOwnProperty(item[2]) && (item[1] === 'asc' || item[1] === 'desc')) result.push({column: item[2], order: item[1]})
}
if(result.length === 0) result.push({column: 'last_name'})
return result
}
private async simpleSearch(qs : string): Promise<{query: string, columns: string[]} | false>{
if (!qs) return false
const regex = /([\w@.]+)(?:\((\w+(?:,\w+)*)\))*/i
const columns = await Database.connection().columnsInfo('employees')
const match = qs.match(regex) ?? []
let result: {
query: string,
columns: string[]
} = {
query: match[1] ?? '',
columns: []
}
match[2]?.split(',').filter(elem => columns.hasOwnProperty(elem.trim())).forEach((col) => {
result.columns.push(col.trim())
})
if(result.columns.length < 1) result.columns = ['first_name', 'last_name']
return result
}
private async select(qs: string): Promise<string[]> {
const columns = await Database.connection().columnsInfo('employees')
let arr = qs.split(',').filter(item => item !== 'password' && item !== '' && columns.hasOwnProperty(item))
if(arr.length === 0) arr = ['id', 'last_name', 'first_name', 'email', 'mobile', 'phone', 'role']
return arr
}
}