Files
arbeitszeitmessung/Backend/models/booking.go
2024-09-07 08:54:52 +02:00

158 lines
3.9 KiB
Go

package models
import (
"database/sql"
"fmt"
"log"
"net/url"
"strconv"
"time"
)
type SameBookingError struct{}
func (e SameBookingError) Error() string {
return "the same booking already exists!"
}
type Booking struct {
CardID string `json:"cardID"`
ReaderID string `json:"readerID"`
BookingType int `json:"bookingType"`
LoggedTime time.Time `json:"loggedTime"`
Id int `json:"id"`
}
var DB *sql.DB
func (b Booking) New(card_id string, reader_id string, booking_type int) Booking {
return Booking{
CardID: card_id,
ReaderID: reader_id,
BookingType: booking_type,
}
}
func (b *Booking) FromUrlParams(params url.Values) Booking {
bookingType, err := strconv.Atoi(params.Get("bookingType"))
if err != nil {
log.Println("Error parsing bookingType: ", err)
return b.New("", "", 0)
}
cardID := params.Get("cardID")
readerID := params.Get("readerID")
return Booking{BookingType: bookingType, CardID: cardID, ReaderID: readerID}
}
func (b Booking) Verify() bool {
if b.CardID == "" || b.ReaderID == "" || b.BookingType == 0 {
return false
}
return true
}
func (b *Booking) Insert() error {
if !checkLastBooking(*b) {
return SameBookingError{}
}
stmt, err := DB.Prepare((`INSERT INTO zeiten (card_id, reader_id, booking_type) VALUES ($1, $2, $3) RETURNING id, logged_time`))
if err != nil {
return err
}
err = stmt.QueryRow(b.CardID, b.ReaderID, b.BookingType).Scan(&b.Id, &b.LoggedTime)
if err != nil {
return err
}
return nil
}
func (b *Booking) GetBookingById(booking_id int) (Booking, error) {
var booking Booking
qStr, err := DB.Prepare((`SELECT id, logged_time, card_id, reader_id, booking_type FROM zeiten WHERE id = $1`))
if err != nil {
return booking, err
}
err = qStr.QueryRow(booking_id).Scan(&booking.Id, &booking.LoggedTime, &booking.CardID, &booking.ReaderID, &booking.BookingType)
if err != nil {
return booking, err
}
if !booking.Verify() {
fmt.Printf("Booking verification failed")
return booking, nil
}
return booking, nil
}
func (b *Booking) GetBookingsByCardID(card_id string) ([]Booking, error) {
qStr, err := DB.Prepare((`SELECT id, logged_time, card_id, reader_id, booking_type FROM zeiten WHERE card_id = $1`))
if err != nil {
return nil, err
}
var bookings []Booking
rows, err := qStr.Query(card_id)
if err == sql.ErrNoRows {
return bookings, err
}
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var booking Booking
if err := rows.Scan(&booking.Id, &booking.LoggedTime, &booking.CardID, &booking.ReaderID, &booking.BookingType); err != nil {
return bookings, err
}
bookings = append(bookings, booking)
}
if err = rows.Err(); err != nil {
return bookings, err
}
return bookings, nil
}
func (b Booking) Save() {
qStr, err := DB.Prepare((`UPDATE "zeiten" SET "id" = $1, "card_id" = $2, "reader_id" = $3, "booking_type" = $4 WHERE "id" = $1;`))
if err != nil {
log.Fatalf("Error preparing query: %v", err)
return
}
_, err = qStr.Query(b.Id, b.CardID, b.ReaderID, b.BookingType)
if err != nil {
log.Fatalf("Error executing query: %v", err)
return
}
}
func (b *Booking) Update(nb Booking) {
if b.BookingType != nb.BookingType && nb.BookingType != 0 {
b.BookingType = nb.BookingType
}
if b.CardID != nb.CardID && nb.CardID != "" {
b.CardID = nb.CardID
}
if b.ReaderID != nb.ReaderID && nb.ReaderID != "" {
b.ReaderID = nb.ReaderID
}
}
func checkLastBooking(b Booking) bool {
var booking_type int
stmt, err := DB.Prepare((`SELECT booking_type FROM "zeiten" WHERE "card_id" = $1 ORDER BY "logged_time" DESC LIMIT 1;`))
if err != nil {
log.Fatalf("Error preparing query: %v", err)
return false
}
err = stmt.QueryRow(b.CardID).Scan(&booking_type)
if err == sql.ErrNoRows {
return true
}
if err != nil {
log.Println("Error checking last booking: ", err)
return false
}
if booking_type == b.BookingType {
return false
}
return true
}