231 lines
6.3 KiB
Go
231 lines
6.3 KiB
Go
package models
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/oklog/ulid/v2"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Project repräsentiert ein Projekt im System
|
|
type Project struct {
|
|
EntityBase
|
|
Name string `gorm:"column:name;not null"`
|
|
CustomerID ulid.ULID `gorm:"column:customer_id;type:uuid;not null"`
|
|
|
|
// Beziehungen (für Eager Loading)
|
|
Customer *Customer `gorm:"foreignKey:CustomerID"`
|
|
}
|
|
|
|
// TableName gibt den Tabellennamen für GORM an
|
|
func (Project) TableName() string {
|
|
return "projects"
|
|
}
|
|
|
|
// ProjectCreate enthält die Felder zum Erstellen eines neuen Projekts
|
|
type ProjectCreate struct {
|
|
Name string
|
|
CustomerID ulid.ULID
|
|
}
|
|
|
|
// ProjectUpdate enthält die aktualisierbaren Felder eines Projekts
|
|
type ProjectUpdate struct {
|
|
ID ulid.ULID `gorm:"-"` // Ausschließen von Updates
|
|
Name *string `gorm:"column:name"`
|
|
CustomerID *ulid.ULID `gorm:"column:customer_id"`
|
|
}
|
|
|
|
// Validate prüft, ob die Create-Struktur gültige Daten enthält
|
|
func (pc *ProjectCreate) Validate() error {
|
|
if pc.Name == "" {
|
|
return errors.New("project name darf nicht leer sein")
|
|
}
|
|
// Prüfung auf gültige CustomerID
|
|
if pc.CustomerID.Compare(ulid.ULID{}) == 0 {
|
|
return errors.New("customerID darf nicht leer sein")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Validate prüft, ob die Update-Struktur gültige Daten enthält
|
|
func (pu *ProjectUpdate) Validate() error {
|
|
if pu.Name != nil && *pu.Name == "" {
|
|
return errors.New("project name darf nicht leer sein")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetProjectByID sucht ein Projekt anhand seiner ID
|
|
func GetProjectByID(ctx context.Context, id ulid.ULID) (*Project, error) {
|
|
var project Project
|
|
result := GetEngine(ctx).Where("id = ?", id).First(&project)
|
|
if result.Error != nil {
|
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
return nil, result.Error
|
|
}
|
|
return &project, nil
|
|
}
|
|
|
|
// GetProjectWithCustomer lädt ein Projekt mit den zugehörigen Kundeninformationen
|
|
func GetProjectWithCustomer(ctx context.Context, id ulid.ULID) (*Project, error) {
|
|
var project Project
|
|
result := GetEngine(ctx).Preload("Customer").Where("id = ?", id).First(&project)
|
|
if result.Error != nil {
|
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
return nil, result.Error
|
|
}
|
|
return &project, nil
|
|
}
|
|
|
|
// GetAllProjects gibt alle Projekte zurück
|
|
func GetAllProjects(ctx context.Context) ([]Project, error) {
|
|
var projects []Project
|
|
result := GetEngine(ctx).Find(&projects)
|
|
if result.Error != nil {
|
|
return nil, result.Error
|
|
}
|
|
return projects, nil
|
|
}
|
|
|
|
// GetAllProjectsWithCustomers gibt alle Projekte mit Kundeninformationen zurück
|
|
func GetAllProjectsWithCustomers(ctx context.Context) ([]Project, error) {
|
|
var projects []Project
|
|
result := GetEngine(ctx).Preload("Customer").Find(&projects)
|
|
if result.Error != nil {
|
|
return nil, result.Error
|
|
}
|
|
return projects, nil
|
|
}
|
|
|
|
// GetProjectsByCustomerID gibt alle Projekte eines bestimmten Kunden zurück
|
|
func GetProjectsByCustomerID(ctx context.Context, customerID ulid.ULID) ([]Project, error) {
|
|
var projects []Project
|
|
result := GetEngine(ctx).Where("customer_id = ?", customerID).Find(&projects)
|
|
if result.Error != nil {
|
|
return nil, result.Error
|
|
}
|
|
return projects, nil
|
|
}
|
|
|
|
// CreateProject erstellt ein neues Projekt mit Validierung
|
|
func CreateProject(ctx context.Context, create ProjectCreate) (*Project, error) {
|
|
// Validierung
|
|
if err := create.Validate(); err != nil {
|
|
return nil, fmt.Errorf("validierungsfehler: %w", err)
|
|
}
|
|
|
|
// Prüfen, ob der Kunde existiert
|
|
customer, err := GetCustomerByID(ctx, create.CustomerID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("fehler beim Prüfen des Kunden: %w", err)
|
|
}
|
|
if customer == nil {
|
|
return nil, errors.New("der angegebene Kunde existiert nicht")
|
|
}
|
|
|
|
project := Project{
|
|
Name: create.Name,
|
|
CustomerID: create.CustomerID,
|
|
}
|
|
|
|
result := GetEngine(ctx).Create(&project)
|
|
if result.Error != nil {
|
|
return nil, fmt.Errorf("fehler beim Erstellen des Projekts: %w", result.Error)
|
|
}
|
|
return &project, nil
|
|
}
|
|
|
|
// UpdateProject aktualisiert ein bestehendes Projekt mit Validierung
|
|
func UpdateProject(ctx context.Context, update ProjectUpdate) (*Project, error) {
|
|
// Validierung
|
|
if err := update.Validate(); err != nil {
|
|
return nil, fmt.Errorf("validierungsfehler: %w", err)
|
|
}
|
|
|
|
project, err := GetProjectByID(ctx, update.ID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if project == nil {
|
|
return nil, errors.New("project nicht gefunden")
|
|
}
|
|
|
|
// Wenn CustomerID aktualisiert wird, prüfen ob der Kunde existiert
|
|
if update.CustomerID != nil {
|
|
customer, err := GetCustomerByID(ctx, *update.CustomerID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("fehler beim Prüfen des Kunden: %w", err)
|
|
}
|
|
if customer == nil {
|
|
return nil, errors.New("der angegebene Kunde existiert nicht")
|
|
}
|
|
}
|
|
|
|
// Generische Update-Funktion verwenden
|
|
if err := UpdateModel(ctx, project, update); err != nil {
|
|
return nil, fmt.Errorf("fehler beim Aktualisieren des Projekts: %w", err)
|
|
}
|
|
|
|
// Aktualisierte Daten aus der Datenbank laden
|
|
return GetProjectByID(ctx, update.ID)
|
|
}
|
|
|
|
// DeleteProject löscht ein Projekt anhand seiner ID
|
|
func DeleteProject(ctx context.Context, id ulid.ULID) error {
|
|
// Hier könnte man prüfen, ob abhängige Entitäten existieren
|
|
result := GetEngine(ctx).Delete(&Project{}, id)
|
|
if result.Error != nil {
|
|
return fmt.Errorf("fehler beim Löschen des Projekts: %w", result.Error)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CreateProjectWithTransaction erstellt ein Projekt innerhalb einer Transaktion
|
|
func CreateProjectWithTransaction(ctx context.Context, create ProjectCreate) (*Project, error) {
|
|
// Validierung
|
|
if err := create.Validate(); err != nil {
|
|
return nil, fmt.Errorf("validierungsfehler: %w", err)
|
|
}
|
|
|
|
var project *Project
|
|
|
|
// Transaktion starten
|
|
err := GetEngine(ctx).Transaction(func(tx *gorm.DB) error {
|
|
// Kundenprüfung innerhalb der Transaktion
|
|
var customer Customer
|
|
if err := tx.Where("id = ?", create.CustomerID).First(&customer).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return errors.New("der angegebene Kunde existiert nicht")
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Projekt erstellen
|
|
newProject := Project{
|
|
Name: create.Name,
|
|
CustomerID: create.CustomerID,
|
|
}
|
|
|
|
if err := tx.Create(&newProject).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// Projekt für die Rückgabe speichern
|
|
project = &newProject
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("transaktionsfehler: %w", err)
|
|
}
|
|
|
|
return project, nil
|
|
}
|