Included user-information in employee Model.

This commit is contained in:
Sockenklaus
2021-11-04 14:00:13 +01:00
parent 63c1407643
commit 3d2e551a8e
13 changed files with 171 additions and 217 deletions

View File

@@ -1,6 +1,5 @@
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'
@@ -8,22 +7,18 @@ import Database from '@ioc:Adonis/Lucid/Database'
import Logger from '@ioc:Adonis/Core/Logger'
type ResultShow = {
employee: {
id: number,
firstName: string,
lastName: string,
lastName: string | undefined,
shorthand: string,
phone: string,
mobile: string,
email: string,
contractHours: number,
hasUser: Boolean,
},
user: {
id?: number,
username?: 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) {
@@ -61,65 +56,46 @@ export default class EmployeesController {
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) {
let result : ResultShow = {
employee: {
id: NaN,
firstName: '',
lastName: '',
shorthand: '',
phone: '',
mobile: '',
email: '',
contractHours: NaN,
hasUser: false
},
user: {}
}
let emp
let user
public async show ({params, bouncer, auth}: HttpContextContract) : Promise<ResultShow> {
let emp: Employee
if(params.id === 'me' && auth.isLoggedIn && auth.user !== undefined){
user = auth.user
emp = (await auth.user.related('employeeProfile').query().limit(1))[0]
emp = auth.user
}
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.shorthand = emp.shorthand
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
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')
@@ -137,6 +113,12 @@ export default class EmployeesController {
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()

View File

@@ -1,6 +1,6 @@
import { DateTime } from 'luxon'
import { BaseModel, belongsTo, BelongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import User from 'App/Models/User'
import { BaseModel, beforeSave, column } from '@ioc:Adonis/Lucid/Orm'
import Hash from '@ioc:Adonis/Core/Hash'
export default class Employee extends BaseModel {
@column({ isPrimary: true })
@@ -22,20 +22,33 @@ export default class Employee extends BaseModel {
public shorthand: string
@column()
public email : string
public email : string | undefined
@column()
public phone : string
public phone : string | undefined
@column()
public mobile : string
public mobile : string | undefined
@column()
public contractHours : number
public contractHours : number | undefined
@column()
public userId : number
public isActive : boolean
@belongsTo(() => User)
public user: BelongsTo<typeof User>
@column()
public role: string
@column()
public username: string | undefined
@column({serializeAs: null})
public password: string
@beforeSave()
public static async hashPassword(employee: Employee){
if(employee.$dirty.password){
employee.password = await Hash.make(employee.password)
}
}
}

View File

@@ -1,41 +0,0 @@
import { DateTime } from 'luxon'
import { BaseModel, beforeSave, column, hasOne, HasOne } from '@ioc:Adonis/Lucid/Orm'
import Hash from '@ioc:Adonis/Core/Hash'
import Employee from 'App/Models/Employee'
export default class User extends BaseModel {
@column({ isPrimary: true })
public id: number
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
@column()
public username: string
@column()
public email: string
@column({serializeAs: null})
public password : string
@hasOne(() => Employee)
public employeeProfile : HasOne<typeof Employee>
@column()
public role : string
@column()
public isActive : boolean
@beforeSave()
public static async hashPassword(user: User) {
if(user.$dirty.password){
user.password = await Hash.make(user.password)
}
}
}

View File

@@ -38,13 +38,15 @@ export default class CreateEmployeeValidator {
trim: true
}),
shorthand: schema.string({
shorthand: schema.string(
{
trim: true
},
[
rules.unique({
table: 'employees',
column: 'shorthand',
caseInsensitive: true,
})
]),
@@ -61,7 +63,40 @@ export default class CreateEmployeeValidator {
mobile: schema.string.optional(),
contractHours: schema.number.optional()
contractHours: schema.number.optional(
[
rules.unsigned(),
rules.range(0, 40)
]
),
role: schema.string(
{
trim: true
}
),
isActive: schema.boolean.optional(),
username: schema.string.optional(
{
trim: true
},
[
rules.unique({
table: 'employees',
column: 'username',
caseInsensitive: true,
})
]
),
password: schema.string.optional(
{},
[
rules.requiredIfExists('username')
]
)
})

View File

@@ -45,6 +45,7 @@ export default class UpdateEmployeeValidator {
rules.unique({
table: 'employees',
column: 'shorthand',
caseInsensitive: true,
whereNot: {
id: this.ctx.params.id
}
@@ -64,7 +65,36 @@ export default class UpdateEmployeeValidator {
mobile: schema.string.optional(),
contractHours: schema.number.optional()
contractHours: schema.number.optional([
rules.unsigned(),
rules.range(0, 40)
]),
role: schema.string({
trim: true
}),
isActive: schema.boolean.optional(),
username: schema.string.optional(
{
trim: true
},
[
rules.unique({
table: 'employees',
column: 'username',
caseInsensitive: true,
})
]
),
password: schema.string.optional(
{},
[
rules.requiredIfExists('username')
]
)
})

View File

@@ -100,7 +100,7 @@ const authConfig: AuthConfig = {
| that time.
|
*/
model: () => import('App/Models/User'),
model: () => import('App/Models/Employee'),
},
},
},

View File

@@ -18,11 +18,15 @@ export default class Employees extends BaseSchema {
table.string('email')
table.string('phone')
table.string('mobile')
table.string('username').unique()
table.string('password')
table.string('role')
.defaultTo('employee')
.notNullable()
table.boolean('is_active')
.defaultTo(false)
.notNullable()
table.decimal('contract_hours', 2, 2)
table
.integer('user_id')
.unsigned()
.references('users.id')
})
}

View File

@@ -1,25 +0,0 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
export default class Users extends BaseSchema {
protected tableName = 'users'
public async up () {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
table.string('username').notNullable().unique()
table.string('email').notNullable().unique()
table.string('password').notNullable()
})
}
public async down () {
this.schema.dropTable(this.tableName)
}
}

View File

@@ -1,23 +0,0 @@
import Hash from '@ioc:Adonis/Core/Hash'
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
import User from 'App/Models/User'
export default class Users extends BaseSchema {
protected tableName = 'users'
public async up () {
this.schema.alterTable(this.tableName, (table) => {
table.boolean('is_active').defaultTo(false)
table.string('role')
.defaultTo('employee')
.notNullable()
})
}
public async down () {
this.schema.alterTable(this.tableName, (table) => {
table.dropColumn('is_active')
table.dropColumn('role')
})
}
}

View File

@@ -6,7 +6,7 @@ export default class ApiTokens extends BaseSchema {
public async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id').primary()
table.integer('user_id').unsigned().references('id').inTable('users').onDelete('CASCADE')
table.integer('user_id').unsigned().references('id').inTable('employee').onDelete('CASCADE')
table.string('name').notNullable()
table.string('type').notNullable()
table.string('token', 64).notNullable().unique()

View File

@@ -11,18 +11,26 @@ export default class EmployeeSeeder extends BaseSeeder {
firstName: 'Max',
lastName: 'Mustermann',
shorthand: 'MM',
userId: 1
username: 'admin',
password: 'admin',
isActive: true,
role: 'admin'
},
{
firstName: 'Jane',
lastName: 'Doe',
shorthand: 'JD',
userId: 2
username: 'user',
password: 'user',
isActive: true,
role: 'employee'
},
{
firstName: 'Bingo',
lastName: 'Bongo',
shorthand: 'BB'
shorthand: 'BB',
isActive: false,
role: 'employee'
}
])
} catch (error) {

View File

@@ -1,28 +0,0 @@
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
import User from 'App/Models/User'
import Logger from '@ioc:Adonis/Core/Logger'
export default class UserSeeder extends BaseSeeder {
public async run () {
try {
await User.create({
username: 'admin',
password: 'admin',
role: 'admin',
email: 'test@test.de',
isActive: true
})
await User.create({
username: 'user',
password: 'user',
role: 'employee',
email: 'user@test.de',
isActive: true
})
}
catch(error) {
Logger.error(error.message)
}
}
}

View File

@@ -6,7 +6,6 @@
*/
import Bouncer from '@ioc:Adonis/Addons/Bouncer'
import User from 'App/Models/User'
import Employee from 'App/Models/Employee'
/*
@@ -33,30 +32,30 @@ import Employee from 'App/Models/Employee'
*/
export const { actions } = Bouncer
.define('employees.index', (user: User) => {
.define('employees.index', (user: Employee) => {
if(user.role !== 'admin') return Bouncer.deny('You are not allowed to view all employees')
return true
})
.define('employees.show', (user: User, employee : Employee) => {
if(user.role !== 'admin' && user.id !== employee.userId){
.define('employees.show', (user: Employee, query: Employee) => {
if(user.role !== 'admin' && user.id !== query.id){
return Bouncer.deny('You are not allowd to view employees other than yourself')
}
return true
})
.define('employees.store', (user: User) => {
.define('employees.store', (user: Employee) => {
if(user.role !== 'admin') return Bouncer.deny('You are not allowd to create any employees')
return true
})
.define('employees.destroy', (user: User) => {
.define('employees.destroy', (user: Employee) => {
if(user.role !== 'admin') return Bouncer.deny('You are not allowed to delete any employees')
return true
})
.define('employees.update', (user: User, editContractHours : boolean, employee: Employee) => {
if(user.id !== employee.userId && user.role !== 'admin'){
.define('employees.update', (user: Employee, editContractHours : boolean, query: Employee) => {
if(user.id !== query.id && user.role !== 'admin'){
return Bouncer.deny('You are not allowed to edit employees other than yourself.')
} else if (editContractHours && user.role !== 'admin'){
return Bouncer.deny('You are not allowed to edit your contract hours.')