100 lines
3.2 KiB
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)
|
|
}
|