time-tracker/docu/code_examples/fpgo_service.go

100 lines
3.2 KiB
Go

// application/timetracking/create_time_entry.go
package main
import (
"context"
"time"
"github.com/google/uuid"
"github.com/username/timetracker/internal/domain/entities"
"github.com/username/timetracker/internal/domain/repositories"
"github.com/username/timetracker/pkg/functional"
"github.com/username/timetracker/pkg/validator"
)
// CreateTimeEntryCommand enthält die Daten zum Erstellen einer Zeitbuchung
type CreateTimeEntryCommand struct {
UserID uuid.UUID
ProjectID uuid.UUID
ActivityID uuid.UUID
TaskID *uuid.UUID
StartTime time.Time
EndTime time.Time
Description string
BillablePercentage int
}
// CreateTimeEntryUseCase repräsentiert den Anwendungsfall zum Erstellen einer Zeitbuchung
type CreateTimeEntryUseCase struct {
timeEntryRepo repositories.TimeEntryRepository
projectRepo repositories.ProjectRepository
activityRepo repositories.ActivityRepository
userRepo repositories.UserRepository
}
// NewCreateTimeEntryUseCase erstellt eine neue Instanz des UseCase
func NewCreateTimeEntryUseCase(
timeEntryRepo repositories.TimeEntryRepository,
projectRepo repositories.ProjectRepository,
activityRepo repositories.ActivityRepository,
userRepo repositories.UserRepository,
) *CreateTimeEntryUseCase {
return &CreateTimeEntryUseCase{
timeEntryRepo: timeEntryRepo,
projectRepo: projectRepo,
activityRepo: activityRepo,
userRepo: userRepo,
}
}
// Execute führt den Anwendungsfall aus
func (uc *CreateTimeEntryUseCase) Execute(ctx context.Context, companyID uuid.UUID, cmd CreateTimeEntryCommand) functional.Result[*entities.TimeEntry] {
// Validierung
if err := validator.ValidateStruct(cmd); err != nil {
return functional.Failure[*entities.TimeEntry](err)
}
// Überprüfen, ob Projekt existiert und zum gleichen Tenant gehört
projectResult := uc.projectRepo.FindByID(ctx, companyID, cmd.ProjectID)
if projectResult.IsFailure() {
return functional.Failure[*entities.TimeEntry](projectResult.Error())
}
// Überprüfen, ob Activity existiert und zum gleichen Tenant gehört
activityResult := uc.activityRepo.FindByID(ctx, companyID, cmd.ActivityID)
if activityResult.IsFailure() {
return functional.Failure[*entities.TimeEntry](activityResult.Error())
}
activity := activityResult.Value()
// Benutzer abrufen für den Stundensatz
userResult := uc.userRepo.FindByID(ctx, companyID, cmd.UserID)
if userResult.IsFailure() {
return functional.Failure[*entities.TimeEntry](userResult.Error())
}
user := userResult.Value()
// Berechnung der Dauer in Minuten
durationMinutes := int(cmd.EndTime.Sub(cmd.StartTime).Minutes())
// TimeEntry erstellen
timeEntry := &entities.TimeEntry{
TenantEntity: entities.TenantEntity{
CompanyID: companyID,
},
UserID: cmd.UserID,
ProjectID: cmd.ProjectID,
ActivityID: cmd.ActivityID,
TaskID: cmd.TaskID,
StartTime: cmd.StartTime,
EndTime: cmd.EndTime,
DurationMinutes: durationMinutes,
Description: cmd.Description,
BillablePercentage: cmd.BillablePercentage,
BillingRate: activity.BillingRate,
}
// Speichern der TimeEntry
return uc.timeEntryRepo.Create(ctx, timeEntry)
}