105 lines
2.8 KiB
Go
105 lines
2.8 KiB
Go
package entities
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// BaseEntity enthält gemeinsame Felder für alle Entitäten
|
|
type BaseEntity struct {
|
|
ID uuid.UUID `gorm:"type:uuid;primary_key"`
|
|
CreatedAt time.Time `gorm:"autoCreateTime"`
|
|
UpdatedAt time.Time `gorm:"autoUpdateTime"`
|
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
|
}
|
|
|
|
// BeforeCreate setzt eine neue UUID vor dem Erstellen
|
|
func (base *BaseEntity) BeforeCreate(tx *gorm.DB) error {
|
|
if base.ID == uuid.Nil {
|
|
base.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// TenantEntity erweitert BaseEntity um Company-ID für Multi-Tenancy
|
|
type TenantEntity struct {
|
|
BaseEntity
|
|
CompanyID uuid.UUID `gorm:"type:uuid;index:idx_tenant"`
|
|
}
|
|
|
|
// Role repräsentiert eine Benutzerrolle
|
|
type Role struct {
|
|
BaseEntity
|
|
Name string `gorm:"unique;not null"`
|
|
Description string
|
|
Permissions []Permission `gorm:"many2many:role_permissions;"`
|
|
}
|
|
|
|
// Permission repräsentiert eine einzelne Berechtigung
|
|
type Permission struct {
|
|
BaseEntity
|
|
Resource string `gorm:"not null"`
|
|
Action string `gorm:"not null"`
|
|
UniqueID string `gorm:"uniqueIndex"`
|
|
}
|
|
|
|
// User repräsentiert einen Benutzer im System
|
|
type User struct {
|
|
TenantEntity
|
|
Email string `gorm:"uniqueIndex;not null"`
|
|
FirstName string
|
|
LastName string
|
|
PasswordHash string `gorm:"not null"`
|
|
RoleID uuid.UUID `gorm:"type:uuid"`
|
|
Role Role `gorm:"foreignKey:RoleID"`
|
|
HourlyRate float64
|
|
IsActive bool `gorm:"default:true"`
|
|
}
|
|
|
|
// FullName gibt den vollständigen Namen des Benutzers zurück
|
|
func (u User) FullName() string {
|
|
return u.FirstName + " " + u.LastName
|
|
}
|
|
|
|
// TimeEntry repräsentiert eine Zeitbuchung
|
|
type TimeEntry struct {
|
|
TenantEntity
|
|
UserID uuid.UUID `gorm:"type:uuid;index:idx_user"`
|
|
User User `gorm:"foreignKey:UserID"`
|
|
ProjectID uuid.UUID `gorm:"type:uuid;index:idx_project"`
|
|
Project Project `gorm:"foreignKey:ProjectID"`
|
|
ActivityID uuid.UUID `gorm:"type:uuid"`
|
|
Activity Activity `gorm:"foreignKey:ActivityID"`
|
|
TaskID *uuid.UUID `gorm:"type:uuid;null"`
|
|
Task *Task `gorm:"foreignKey:TaskID"`
|
|
StartTime time.Time `gorm:"not null;index:idx_time_range"`
|
|
EndTime time.Time `gorm:"not null;index:idx_time_range"`
|
|
DurationMinutes int `gorm:"not null"`
|
|
Description string
|
|
BillablePercentage int `gorm:"default:100"`
|
|
BillingRate float64
|
|
}
|
|
|
|
type Project struct {
|
|
TenantEntity
|
|
Name string
|
|
}
|
|
|
|
type Activity struct {
|
|
TenantEntity
|
|
Name string
|
|
}
|
|
|
|
type Task struct {
|
|
TenantEntity
|
|
Name string
|
|
}
|
|
|
|
// CalculateBillableAmount berechnet den abrechenbaren Betrag
|
|
func (t TimeEntry) CalculateBillableAmount() float64 {
|
|
hours := float64(t.DurationMinutes) / 60.0
|
|
return hours * t.BillingRate * (float64(t.BillablePercentage) / 100.0)
|
|
}
|