package database import ( "fmt" "log" "time" "gittea.marcokittel.de/elio/eliotools/datawriter/internal/models" "golang.org/x/net/context" ) type ProductService struct { dbr *DatabaseReader } func NewOutgoingProducts() *models.OutgoingProducts { op := models.OutgoingProducts{ Products: make(map[string][]models.Product), } return &op } func NewOutgoingReservationsProducts(groupId models.UUID) *models.OutgoingReservationProducts { op := models.OutgoingReservationProducts{ Id: groupId, Products: make(map[string][]models.Product), } return &op } type Context struct { Country string `json:"country"` State string `json:"state"` } func NewProductService(ctx context.Context, connectionString string) *ProductService { dbr := NewDatabaseReader(ctx, connectionString) p := ProductService{dbr: dbr} return &p } func (p *ProductService) Autorelease() { //Das müsste saubererer sein. Spare ich mir aber, weil der Webserver alles blockiert. //Besser wäre das Arbeiten mit Context. Gefahr ist aber minimal go func() { for { fmt.Println("Prüfe nach Registrierungen die Freigegeben werden können. (Älter als 24 Stunden)") err := p.dbr.ReleaseReservierungenAfterOneDay() if err != nil { log.Printf("Fehler beim Ausführen von Autorelease() des Logs. %s", err) } time.Sleep(30 * time.Second) } }() } func (p *ProductService) ReserviereBestellungen(op []models.OutgoingReservationProducts, groupId models.UUID) (*[]models.UUID, error) { var uuids []models.UUID for _, hsmp := range op { for _, prod := range hsmp.Products { for _, concreteProduct := range prod { deliveryId := concreteProduct.DeliveryId warehouseId := concreteProduct.WhdId amount := concreteProduct.Quantity // Todo: Handler Injection wäre hier interessant uuid, err := p.dbr.ReserveReservationItem(deliveryId, warehouseId, amount, groupId) if err != nil { return nil, err } uuids = append(uuids, uuid) } } } return &uuids, nil } func (p *ProductService) ConfirmBestellung(groudId models.UUID) error { return p.dbr.ConfirmReservationGroup(groudId) } func (p *ProductService) AbortBestellung(groudId models.UUID) error { return p.dbr.AbortReservationGroup(groudId) } func (p *ProductService) ReleaseBestellung(groudId models.UUID) error { return p.dbr.ReleaseReservationGroup(groudId) } func (p *ProductService) FetchData(payload *models.Container) ([]models.OutgoingProducts, error) { result := []models.OutgoingProducts{} for key, item := range payload.Products { //Checken ob die Felder leer sind / Validitätsprüfung einbauen products, err := p.dbr.GetProductByProductIdDeliveryCountryAndState(key, payload.Context.Country, payload.Context.State) if err != nil { return nil, err } if len(products) == 0 { continue } gebrauchteProduktAnzahl := item op := NewOutgoingProducts() for _, db_products := range products { if gebrauchteProduktAnzahl <= 0 { continue } if db_products.Amount >= gebrauchteProduktAnzahl { newProduct := models.Product{Delivery: db_products.DeliveryDays, Quantity: gebrauchteProduktAnzahl, Warehouse: db_products.Warehouse, WhdId: db_products.Id, DeliveryId: db_products.DeliveryId} gebrauchteProduktAnzahl = 0 op.Products[key] = append(op.Products[key], newProduct) } else if db_products.Amount < gebrauchteProduktAnzahl { newProduct := models.Product{Delivery: db_products.DeliveryDays, Quantity: db_products.Amount, Warehouse: db_products.Warehouse, WhdId: db_products.Id, DeliveryId: db_products.DeliveryId} gebrauchteProduktAnzahl -= db_products.Amount op.Products[key] = append(op.Products[key], newProduct) } } result = append(result, *op) } return result, nil } func (p *ProductService) FetchReservationData(payload *models.Container, groupId models.UUID) ([]models.OutgoingReservationProducts, error) { result := []models.OutgoingReservationProducts{} for key, item := range payload.Products { //Checken ob die Felder leer sind / Validitätsprüfung einbauen products, err := p.dbr.GetProductByProductIdDeliveryCountryAndState(key, payload.Context.Country, payload.Context.State) if err != nil { return nil, err } if len(products) == 0 { continue } gebrauchteProduktAnzahl := item op := NewOutgoingReservationsProducts(groupId) for _, db_products := range products { if gebrauchteProduktAnzahl <= 0 { continue } if db_products.Amount >= gebrauchteProduktAnzahl { newProduct := models.Product{Delivery: db_products.DeliveryDays, Quantity: gebrauchteProduktAnzahl, Warehouse: db_products.Warehouse, WhdId: db_products.Id, DeliveryId: db_products.DeliveryId} gebrauchteProduktAnzahl = 0 op.Products[key] = append(op.Products[key], newProduct) } else if db_products.Amount < gebrauchteProduktAnzahl { newProduct := models.Product{Delivery: db_products.DeliveryDays, Quantity: db_products.Amount, Warehouse: db_products.Warehouse, WhdId: db_products.Id, DeliveryId: db_products.DeliveryId} gebrauchteProduktAnzahl -= db_products.Amount op.Products[key] = append(op.Products[key], newProduct) } } result = append(result, *op) } return result, nil }