import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' import Employee from 'App/Models/Employee' import User from 'App/Models/User' import UpdateEmployeeValidator from 'App/Validators/UpdateEmployeeValidator' import CreateEmployeeValidator from 'App/Validators/CreateEmployeeValidator' import Database from '@ioc:Adonis/Lucid/Database' import Logger from '@ioc:Adonis/Core/Logger' type ResultShow = { employee: { id: number, firstName: string, lastName: string, shorthand: string, phone: string, mobile: string, email: string, contractHours: number, hasUser: Boolean, }, user: { id?: number, username?: string } } 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 sortBy = await this.sortBy(request.qs().sort_by) const simpleSearch = await this.simpleSearch(request.qs().simple_search) const employees = Database.query() employees.from('employees') 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, }) } catch (error) { return error } } public async show ({params, bouncer, auth}: HttpContextContract) { let result : ResultShow = { employee: { id: NaN, firstName: '', lastName: '', shorthand: '', phone: '', mobile: '', email: '', contractHours: NaN, hasUser: false }, user: {} } let emp let user if(params.id === 'me' && auth.isLoggedIn && auth.user !== undefined){ user = auth.user emp = (await auth.user.related('employeeProfile').query().limit(1))[0] } else { emp = await Employee.findOrFail(params.id) user = (await User.find(emp.userId)) ?? undefined } if(emp !== undefined){ result.employee.id = emp.id result.employee.firstName = emp.firstName result.employee.lastName = emp.lastName result.employee.phone = emp.phone result.employee.mobile = emp.mobile result.employee.email = emp.email result.employee.contractHours = emp.contractHours } if(user !== undefined){ result.employee.hasUser = true result.user.username = user.username result.user.id = user.id } await bouncer.authorize('employees.show', emp) return result } 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 ?? '' 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 } }