363 lines
8.2 KiB
Go
363 lines
8.2 KiB
Go
package training
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/shopspring/decimal"
|
|
"gitlab.mareshq.com/hq/yggdrasil/internal/currency"
|
|
)
|
|
|
|
type TrainingRepository interface {
|
|
Create(training *Training) error
|
|
FindByID(id TrainingID) (*Training, error)
|
|
FindAll() ([]Training, error)
|
|
Update(training *Training) error
|
|
Delete(id TrainingID) error
|
|
}
|
|
|
|
type InMemoryTrainingRepository struct {
|
|
trainings map[TrainingID]Training
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
func NewInMemoryTrainingRepository() *InMemoryTrainingRepository {
|
|
repo := &InMemoryTrainingRepository{
|
|
trainings: make(map[TrainingID]Training),
|
|
}
|
|
|
|
_ = repo.Create(&Training{
|
|
Name: "Kubernetes",
|
|
Days: 2,
|
|
Description: "Kubernetes",
|
|
Pricing: []TrainingPrice{
|
|
{
|
|
Amount: decimal.NewFromInt(450),
|
|
Currency: currency.USD,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(2000),
|
|
Currency: currency.USD,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(9900),
|
|
Currency: currency.CZK,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(49000),
|
|
Currency: currency.CZK,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
},
|
|
})
|
|
_ = repo.Create(&Training{
|
|
Name: "Terraform",
|
|
Days: 1,
|
|
Description: "Terraform",
|
|
Pricing: []TrainingPrice{
|
|
{
|
|
Amount: decimal.NewFromInt(200),
|
|
Currency: currency.USD,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(1000),
|
|
Currency: currency.USD,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(4900),
|
|
Currency: currency.CZK,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(24000),
|
|
Currency: currency.CZK,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
},
|
|
})
|
|
_ = repo.Create(&Training{
|
|
Name: "RKE2",
|
|
Days: 1,
|
|
Description: "RKE2",
|
|
Pricing: []TrainingPrice{
|
|
{
|
|
Amount: decimal.NewFromInt(200),
|
|
Currency: currency.USD,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(1000),
|
|
Currency: currency.USD,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(4900),
|
|
Currency: currency.CZK,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(24000),
|
|
Currency: currency.CZK,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
},
|
|
})
|
|
_ = repo.Create(&Training{
|
|
Name: "GitHub Actions",
|
|
Days: 1,
|
|
Description: "GitHub Actions",
|
|
Pricing: []TrainingPrice{
|
|
{
|
|
Amount: decimal.NewFromInt(200),
|
|
Currency: currency.USD,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(1000),
|
|
Currency: currency.USD,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(4900),
|
|
Currency: currency.CZK,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(24000),
|
|
Currency: currency.CZK,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
},
|
|
})
|
|
_ = repo.Create(&Training{
|
|
Name: "GitLab CI",
|
|
Days: 1,
|
|
Description: "GitLab CI",
|
|
Pricing: []TrainingPrice{
|
|
{
|
|
Amount: decimal.NewFromInt(200),
|
|
Currency: currency.USD,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(1000),
|
|
Currency: currency.USD,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(4900),
|
|
Currency: currency.CZK,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(24000),
|
|
Currency: currency.CZK,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
},
|
|
})
|
|
_ = repo.Create(&Training{
|
|
Name: "Prometheus",
|
|
Days: 2,
|
|
Description: "Prometheus",
|
|
Pricing: []TrainingPrice{
|
|
{
|
|
Amount: decimal.NewFromInt(450),
|
|
Currency: currency.USD,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(2000),
|
|
Currency: currency.USD,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(9900),
|
|
Currency: currency.CZK,
|
|
Type: OpenTrainingPrice,
|
|
},
|
|
{
|
|
Amount: decimal.NewFromInt(49000),
|
|
Currency: currency.CZK,
|
|
Type: CorporateTrainingPrice,
|
|
},
|
|
},
|
|
})
|
|
|
|
return repo
|
|
}
|
|
|
|
func (r *InMemoryTrainingRepository) Create(training *Training) error {
|
|
r.lock.Lock()
|
|
defer r.lock.Unlock()
|
|
|
|
training.ID = NewTrainingID()
|
|
r.trainings[training.ID] = *training
|
|
return nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingRepository) FindByID(id TrainingID) (*Training, error) {
|
|
r.lock.RLock()
|
|
defer r.lock.RUnlock()
|
|
|
|
training, ok := r.trainings[id]
|
|
if !ok {
|
|
return nil, ErrTrainingNotFound
|
|
}
|
|
return &training, nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingRepository) FindAll() ([]Training, error) {
|
|
r.lock.RLock()
|
|
defer r.lock.RUnlock()
|
|
|
|
trainings := make([]Training, 0, len(r.trainings))
|
|
for _, training := range r.trainings {
|
|
trainings = append(trainings, training)
|
|
}
|
|
return trainings, nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingRepository) Update(training *Training) error {
|
|
r.lock.Lock()
|
|
defer r.lock.Unlock()
|
|
|
|
r.trainings[training.ID] = *training
|
|
return nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingRepository) Delete(id TrainingID) error {
|
|
r.lock.Lock()
|
|
defer r.lock.Unlock()
|
|
|
|
_, ok := r.trainings[id]
|
|
if !ok {
|
|
return ErrTrainingNotFound
|
|
}
|
|
|
|
delete(r.trainings, id)
|
|
return nil
|
|
}
|
|
|
|
type TrainingDateRepository interface {
|
|
Create(trainingID TrainingID, trainingDate *TrainingDate) error
|
|
FindByID(id TrainingDateID) (*TrainingDate, error)
|
|
FindAll() ([]TrainingDate, error)
|
|
FindAllByTrainingID(trainingID TrainingID) ([]TrainingDate, error)
|
|
FindUpcomingByTrainingID(trainingID TrainingID) ([]TrainingDate, error)
|
|
Update(trainingDate *TrainingDate) error
|
|
Delete(id TrainingDateID) error
|
|
}
|
|
|
|
type InMemoryTrainingDateRepository struct {
|
|
trainingDates map[TrainingDateID]TrainingDate
|
|
trainingToDates map[TrainingID][]TrainingDateID
|
|
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
func NewInMemoryTrainingDateRepository() *InMemoryTrainingDateRepository {
|
|
return &InMemoryTrainingDateRepository{
|
|
trainingDates: make(map[TrainingDateID]TrainingDate),
|
|
trainingToDates: make(map[TrainingID][]TrainingDateID),
|
|
}
|
|
}
|
|
|
|
func (r *InMemoryTrainingDateRepository) Create(trainingID TrainingID, trainingDate *TrainingDate) error {
|
|
r.lock.Lock()
|
|
defer r.lock.Unlock()
|
|
|
|
trainingDate.ID = NewTrainingDateID()
|
|
trainingDate.trainingID = trainingID
|
|
|
|
r.trainingDates[trainingDate.ID] = *trainingDate
|
|
r.trainingToDates[trainingID] = append(r.trainingToDates[trainingID], trainingDate.ID)
|
|
return nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingDateRepository) FindByID(id TrainingDateID) (*TrainingDate, error) {
|
|
r.lock.RLock()
|
|
defer r.lock.RUnlock()
|
|
|
|
date, ok := r.trainingDates[id]
|
|
if !ok {
|
|
return nil, ErrTrainingDateNotFound
|
|
}
|
|
return &date, nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingDateRepository) FindAll() ([]TrainingDate, error) {
|
|
r.lock.RLock()
|
|
defer r.lock.RUnlock()
|
|
|
|
dates := make([]TrainingDate, len(r.trainingDates))
|
|
for _, date := range r.trainingDates {
|
|
dates = append(dates, date)
|
|
}
|
|
|
|
return dates, nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingDateRepository) FindAllByTrainingID(trainingID TrainingID) ([]TrainingDate, error) {
|
|
r.lock.RLock()
|
|
defer r.lock.RUnlock()
|
|
|
|
dates := make([]TrainingDate, 0)
|
|
for _, id := range r.trainingToDates[trainingID] {
|
|
dates = append(dates, r.trainingDates[id])
|
|
}
|
|
|
|
return dates, nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingDateRepository) FindUpcomingByTrainingID(trainingID TrainingID) ([]TrainingDate, error) {
|
|
r.lock.RLock()
|
|
defer r.lock.RUnlock()
|
|
|
|
now := time.Now()
|
|
var dates []TrainingDate
|
|
for _, id := range r.trainingToDates[trainingID] {
|
|
date := r.trainingDates[id]
|
|
if date.Date.After(now) {
|
|
dates = append(dates, date)
|
|
}
|
|
}
|
|
|
|
return dates, nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingDateRepository) Update(trainingDate *TrainingDate) error {
|
|
r.lock.Lock()
|
|
defer r.lock.Unlock()
|
|
|
|
oldDate := r.trainingDates[trainingDate.ID]
|
|
trainingDate.trainingID = oldDate.trainingID
|
|
r.trainingDates[trainingDate.ID] = *trainingDate
|
|
return nil
|
|
}
|
|
|
|
func (r *InMemoryTrainingDateRepository) Delete(id TrainingDateID) error {
|
|
r.lock.Lock()
|
|
defer r.lock.Unlock()
|
|
|
|
date, ok := r.trainingDates[id]
|
|
if !ok {
|
|
return ErrTrainingDateNotFound
|
|
}
|
|
|
|
delete(r.trainingDates, id)
|
|
dates := r.trainingToDates[date.trainingID]
|
|
for idx, d := range dates {
|
|
if d == id {
|
|
r.trainingToDates[date.trainingID] = append(dates[:idx], dates[idx+1:]...)
|
|
break
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|