Files
arbeitszeitmessung/Backend/models/user.go

211 lines
5.6 KiB
Go

package models
import (
"arbeitszeitmessung/helper"
"context"
"database/sql"
"errors"
"fmt"
"log"
"time"
"github.com/alexedwards/scs/v2"
)
type User struct {
CardUID string `json:"card_uid"`
Name string `json:"name"`
Vorname string `json:"vorname"`
PersonalNummer int `json:"personal_nummer"`
Arbeitszeit float32 `json:"arbeitszeit"`
}
func (u *User) GetUserFromSession(Session *scs.SessionManager, ctx context.Context) (User, error) {
var user User
var err error
if helper.GetEnv("GO_ENV", "production") == "debug" {
user, err = (*User).GetByPersonalNummer(nil, 123)
} else {
if !Session.Exists(ctx, "user") {
log.Println("No user in session storage!")
return user, errors.New("No user in session storage!")
}
user, err = (*User).GetByPersonalNummer(nil, Session.GetInt(ctx, "user"))
}
if err != nil {
log.Println("Cannot get user from session!")
return user, err
}
return user, nil
}
func (u *User) GetAll() ([]User, error) {
qStr, err := DB.Prepare((`SELECT card_uid, vorname, nachname FROM personal_daten;`))
var users []User
if err != nil {
fmt.Printf("Error preparing query statement %v\n", err)
return users, err
}
defer qStr.Close()
rows, err := qStr.Query()
if err != nil {
return users, err
}
defer rows.Close()
for rows.Next() {
var user User
if err := rows.Scan(&user.CardUID, &user.Vorname, &user.Name); err != nil {
return users, nil
}
users = append(users, user)
}
if err = rows.Err(); err != nil {
return users, nil
}
return users, nil
}
// Returns true if there is a booking 1 for today -> meaning the user is at work
// Returns false if there is no booking today or the user is already booked out of the system
func (u *User) CheckAnwesenheit() bool {
qStr, err := DB.Prepare((`SELECT check_in_out FROM anwesenheit WHERE card_uid = $1 AND "timestamp" >= now()::date + interval '1h' ORDER BY "timestamp" DESC`))
if err != nil {
fmt.Printf("Error preparing query statement %v\n", err)
return false
}
defer qStr.Close()
var check_in_out int
err = qStr.QueryRow(u.CardUID).Scan(&check_in_out)
if err != nil {
return false
}
return check_in_out == 1
}
// Creates a new booking for the user -> check_in_out will be 255 for automatic check out
func (u *User) Logout() error {
booking := (*Booking).New(nil, u.CardUID, 0, 255)
err := booking.Insert()
if err != nil {
fmt.Printf("Error inserting booking %v\n", err)
return err
}
return nil
}
func (u *User) GetByPersonalNummer(personalNummer int) (User, error) {
var user User
qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname, arbeitszeit_per_tag FROM personal_daten WHERE personal_nummer = $1;`))
if err != nil {
return user, err
}
err = qStr.QueryRow(personalNummer).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.Arbeitszeit)
if err != nil {
return user, err
}
return user, nil
}
func (u *User) Login(password string) bool {
var loginSuccess bool
qStr, err := DB.Prepare((`SELECT (pass_hash = crypt($2, pass_hash)) AS pass_hash FROM user_password WHERE personal_nummer = $1;`))
if err != nil {
log.Println("Error preparing db statement", err)
return false
}
defer qStr.Close()
err = qStr.QueryRow(u.PersonalNummer, password).Scan(&loginSuccess)
if err != nil {
log.Println("Error queriing db", err)
return false
}
return loginSuccess
}
// checks if old password matches and changes to new password
//
// returns auth(bool), error
func (u *User) ChangePass(password, newPassword string) (bool, error) {
if !u.Login(password) {
return false, nil
}
qStr, err := DB.Prepare((`UPDATE user_password SET pass_hash = crypt($2, gen_salt('bf')) WHERE personal_nummer = $1;`))
if err != nil {
return false, err
}
_, err = qStr.Exec(u.PersonalNummer, newPassword)
if err != nil {
return false, err
}
return true, nil
}
func (u *User) GetTeamMembers() ([]User, error) {
var teamMembers []User
qStr, err := DB.Prepare(`SELECT personal_nummer, card_uid, vorname, nachname, arbeitszeit_per_tag FROM personal_daten WHERE vorgesetzter_pers_nr = $1`)
if err != nil {
return teamMembers, err
}
defer qStr.Close()
rows, err := qStr.Query(u.PersonalNummer)
if err != nil {
log.Println("Error getting rows!")
return teamMembers, err
}
defer rows.Close()
for rows.Next() {
user, err := parseUser(rows)
if err != nil {
log.Println("Error parsing user!")
return teamMembers, err
}
teamMembers = append(teamMembers, user)
}
return teamMembers, nil
}
func (u *User) GetWeek(tsFrom time.Time) WorkWeek {
var bookings []WorkDay
weekStart := tsFrom.AddDate(0, 0, -1*int(tsFrom.Local().Weekday())-1)
bookings, err := (*Booking).GetBookingsGrouped(nil, u.CardUID, weekStart, time.Now())
if err != nil {
log.Println("Error fetching bookings!")
return WorkWeek{WorkDays: bookings}
}
return WorkWeek{WorkDays: bookings}
}
// gets the first week, that needs to be submitted
func (u *User) GetNextWeek() WorkWeek {
var week WorkWeek
return week
}
func parseUser(rows *sql.Rows) (User, error) {
var user User
if err := rows.Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.Arbeitszeit); err != nil {
log.Println("Error scanning row!", err)
return user, err
}
return user, nil
}
func (u *User) GetLastSubmission() time.Time {
var lastSub time.Time
qStr, err := DB.Prepare("SELECT woche_start FROM buchung_wochen WHERE personal_nummer = $1 ORDER BY woche_start DESC LIMIT 1")
if err != nil {
log.Println("Error preparing statement!", err)
return lastSub
}
err = qStr.QueryRow(u.PersonalNummer).Scan(&lastSub)
if err != nil {
log.Println("Error executing query!", err)
return lastSub
}
return lastSub
}