Compare commits

...
8 Commits
Author SHA1 Message Date
tsindt 62af3f17f2 Tree steht 2026-09-16 16:32:31 +02:00
tsindt c755a80b47 test 2026-09-15 23:03:10 +02:00
tsindt dcb6295091 Propertytypegroups-Tree 2026-09-15 19:27:04 +02:00
tsindt 33acfb0bfc Datebimport 2026-09-15 13:22:53 +02:00
tsindt 6feaaa56eb Bugfixing import properties 2026-09-14 23:11:02 +02:00
tsindt 25b3923427 Property Import 2026-09-14 21:15:09 +02:00
tsindt a7ef4e52ca Merge branch 'main' of https://barefacedgit.ddnss.de/tsindt/simply_cpq 2026-09-14 08:52:58 +02:00
tsindt c62aa67220 Test 2026-09-14 08:52:52 +02:00
29 changed files with 1255 additions and 198 deletions
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}"
}
]
}
@@ -1,206 +1,206 @@
[
{
"label": "X-CPQ",
"name": "X-CPQ",
"description": "Property Type Group for X-CPQ",
"propertyTypeGroups": [
"property_type_Groups": [
{
"label": "electrical",
"name": "electrical",
"description": "All electrical property types",
"propertyTypes": [
"property_types": [
{
"label": "Spannungsversorgung (V)",
"name": "Spannungsversorgung (V)",
"description": "Spannungsversorgung (V)",
"values": [
220,
230
{ "value": 220 },
{ "value": 230 }
]
},
{
"label": "Leistung (W)",
"name": "Leistung (W)",
"description": "Leistung",
"values": [
0,
140,
130,
120,
110,
100,
90,
80,
70,
60,
50,
28,
26,
24,
22,
20
{ "value": 0 },
{ "value": 140 },
{ "value": 130 },
{ "value": 120 },
{ "value": 110 },
{ "value": 100 },
{ "value": 90 },
{ "value": 80 },
{ "value": 70 },
{ "value": 60 },
{ "value": 50 },
{ "value": 28 },
{ "value": 26 },
{ "value": 24 },
{ "value": 22 },
{ "value": 20 }
]
},
{
"label": "Eingangsimpedanz (Ω)",
"name": "Eingangsimpedanz (Ω)",
"description": "Wiederstand der Eingangsimpedanz",
"values": [
10
{ "value": 10 }
]
},
{
"label": "Frequenzbereich (Hz‑kHz)",
"name": "Frequenzbereich (Hz‑kHz)",
"description": "Frequenzbereich (Hz‑kHz)",
"values": [
"87‑108"
{ "value": "87‑108" }
]
},
{
"label": "Signal‑Rausch‑Verhältnis (dB)",
"name": "Signal‑Rausch‑Verhältnis (dB)",
"description": "Signal‑Rausch‑Verhältnis (dB)",
"values": [
48,
46,
47,
45,
49,
44
{ "value": 48 },
{ "value": 46 },
{ "value": 47 },
{ "value": 45 },
{ "value": 49 },
{ "value": 44 }
]
},
{
"label": "Anschlüsse",
"name": "Anschlüsse",
"description": "Anschlüsse",
"values": [
"UKW+Bluetooth+DL",
"UKW+Wi‑Fi+DL",
"UKW+DL+Bluetooth",
"UKW+Bluetooth+Wi‑Fi",
"UKW+Wi‑Fi+DL",
"UKW+Wi‑Fi",
"UKW+Bluetooth",
"UKW+DL",
"UKW"
{ "value": "UKW+Bluetooth+DL" },
{ "value": "UKW+Wi‑Fi+DL" },
{ "value": "UKW+DL+Bluetooth" },
{ "value": "UKW+Bluetooth+Wi‑Fi" },
{ "value": "UKW+Wi‑Fi+DL" },
{ "value": "UKW+Wi‑Fi" },
{ "value": "UKW+Bluetooth" },
{ "value": "UKW+DL" },
{ "value": "UKW" }
]
},
{
"label": "Ausgangsimpedanz (Ω)",
"name": "Ausgangsimpedanz (Ω)",
"description": "Ausgangsimpedanz (Ω)",
"values": [
75
{ "value": 75 }
]
}
]
},
{
"label": "mechanical",
"name": "mechanical",
"description": "All mechanical properties",
"propertyTypes": [
"property_types": [
{
"label": "Abmessungen (mm)",
"name": "Abmessungen (mm)",
"description": "All mechanical properties",
"values": [
"158x88x33",
"310x210x110",
"160x90x35",
"170x100x42",
"150x80x30",
"155x85x32",
"165x95x38",
"305x205x105",
"172x102x44",
"340x240x140",
"420x320x140",
"162x92x36",
"300x200x100",
"168x98x40",
"315x215x115",
"325x225x125",
"415x315x135",
"320x220x120",
"335x235x135",
"330x230x130",
"400x300x120",
"405x305x125",
"345x245x145",
"295x245x135",
"410x310x130",
"290x240x130",
"285x235x125",
"280x230x120",
"275x225x115",
"270x220x110",
"265x215x105",
"255x205x95",
"260x210x100",
"250x200x90",
"445x345x165",
"440x340x160",
"435x335x155",
"430x330x150",
"425x325x145"
{ "value": "158x88x33" },
{ "value": "310x210x110" },
{ "value": "160x90x35" },
{ "value": "170x100x42" },
{ "value": "150x80x30" },
{ "value": "155x85x32" },
{ "value": "165x95x38" },
{ "value": "305x205x105" },
{ "value": "172x102x44" },
{ "value": "340x240x140" },
{ "value": "420x320x140" },
{ "value": "162x92x36" },
{ "value": "300x200x100" },
{ "value": "168x98x40" },
{ "value": "315x215x115" },
{ "value": "325x225x125" },
{ "value": "415x315x135" },
{ "value": "320x220x120" },
{ "value": "335x235x135" },
{ "value": "330x230x130" },
{ "value": "400x300x120" },
{ "value": "405x305x125" },
{ "value": "345x245x145" },
{ "value": "295x245x135" },
{ "value": "410x310x130" },
{ "value": "290x240x130" },
{ "value": "285x235x125" },
{ "value": "280x230x120" },
{ "value": "275x225x115" },
{ "value": "270x220x110" },
{ "value": "265x215x105" },
{ "value": "255x205x95" },
{ "value": "260x210x100" },
{ "value": "250x200x90" },
{ "value": "445x345x165" },
{ "value": "440x340x160" },
{ "value": "435x335x155" },
{ "value": "430x330x150" },
{ "value": "425x325x145" }
]
},
{
"label": "Gewicht (kg)",
"name": "Gewicht (kg)",
"description": "All mechanical properties",
"values": [
3,
6,
4,
2
{ "value": 3 },
{ "value": 6 },
{ "value": 4 },
{ "value": 2 }
]
},
{
"label": "Kapazität (kg)",
"name": "Kapazität (kg)",
"description": "All mechanical properties",
"values": [
0
{ "value": 0 }
]
},
{
"label": "Programms/Features",
"name": "Programms/Features",
"description": "All mechanical properties",
"values": []
},
{
"label": "Wasserverbrauch pro Zyklus (L)",
"name": "Wasserverbrauch pro Zyklus (L)",
"description": "All mechanical properties",
"values": []
},
{
"label": "Material Innenraum",
"name": "Material Innenraum",
"description": "All mechanical properties",
"values": []
},
{
"label": "Kapazität/Volumen (L)",
"name": "Kapazität/Volumen (L)",
"description": "All mechanical properties",
"values": []
},
{
"label": "Schleuderdrehzahl (U/min)",
"name": "Schleuderdrehzahl (U/min)",
"description": "All mechanical properties",
"values": []
}
]
},
{
"label": "other",
"name": "other",
"description": "All other properties",
"propertyTypes": [
"property_types": [
{
"label": "Preis (USD)",
"name": "Preis (USD)",
"description": "All other properties",
"values": []
},
{
"label": "Zusatzfunktionen",
"name": "Zusatzfunktionen",
"description": "All other properties",
"values": []
},
{
"label": "Bedienungsart",
"name": "Bedienungsart",
"description": "All other properties",
"values": []
},
{
"label": "Energieeffizienzklasse",
"name": "Energieeffizienzklasse",
"description": "All other properties",
"values": []
}
+10 -8
View File
@@ -34,18 +34,20 @@ go get github.com/gin-contrib/cors
go get github.com/gin-contrib/sessions
````
##### Go Air
Go Air ist ein Live-Reload-Tool für Go-Anwendungen, das die Entwicklungsproduktivität erhöht.
````
go install github.com/air-verse/air@latest
export PATH="$PATH:$(go env GOPATH)/bin"
````
Den Export ggf. in der .bashrc oder .zshrc hinzufügen.
#### HTML Erweiterungen
ggf. später lokal runter laden ...
##### Tailwind und DaisyUI
Tailwind ist ein CSS Framework, das die Erstellung von Webseiten erleichtert. DaisyUI ist eine Erweiterung von Tailwind, die zusätzliche Komponenten bereitstellt.
````
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
````
##### HTMX
HTMX ist eine JavaScript-Bibliothek, die es ermöglicht, HTML direkt über AJAX-Anfragen zu aktualisieren.
+2 -2
View File
@@ -4,8 +4,8 @@
# password=<databaseUserPassword> dbname=<databaseName>
[database]
##connection_string = "host=192.168.178.50 port=5432 user=tsindt password=XD14ko8d dbname=xcpq sslmode=disable"
connection_string = "host=localhost port=5432 user=tsindt password=XD14ko8d dbname=xcpq sslmode=disable"
connection_string = "host=192.168.178.50 port=5432 user=tsindt password=XD14ko8d dbname=xcpq sslmode=disable"
##connection_string = "host=localhost port=5432 user=tsindt password=XD14ko8d dbname=xcpq sslmode=disable"
driver_name = "postgres"
################################################################
@@ -5,6 +5,8 @@ import (
"log"
"net/http"
"xcpq_editor/internal/handlers"
"xcpq_editor/internal/repositories"
"xcpq_editor/internal/services"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
@@ -12,40 +14,76 @@ import (
)
type HttpServer struct {
config *viper.Viper
router *gin.Engine
dbHandler *sql.DB
config *viper.Viper
router *gin.Engine
dbHandler *sql.DB
importHandler *handlers.ImportHandler
importRepository *repositories.Import_Repository
valueRepository *repositories.Value_Repository
propertyRepository *repositories.Property_Repository
propertyTypeRepository *repositories.Property_Type_Repository
propertyTypeGroupRepository *repositories.Property_Types_Group_Repository
}
func InitHttpServer(config *viper.Viper, dbHandler *sql.DB) HttpServer {
// db initialization can be done here if needed
// repository initialisation:
valueRepository := repositories.NewValueRepository(dbHandler)
propertyRepository := repositories.NewPropertyRepository(dbHandler, valueRepository)
propertyTypeRepository := repositories.NewPropertyTypeRepository(dbHandler, propertyRepository)
propertyTypeGroupRepository := repositories.NewPropertyTypesGroupRepository(dbHandler, propertyTypeRepository)
importRepository := repositories.NewImportRepository(dbHandler, valueRepository, propertyTypeRepository, propertyTypeGroupRepository, propertyRepository)
// service initialisation:
importService := services.NewImportService(importRepository)
propertyTypesService := services.NewPropertyTypeService(propertyTypeRepository, propertyTypeGroupRepository)
// controller initialisation:
// handler initialisation:
importHandler := handlers.NewImportHandler(importService)
propertyTypesHandler := handlers.NewPropertyTypesHandler(propertyTypesService)
// Service API
router := gin.Default()
// initialize templates
router.LoadHTMLGlob("../templates/**/*.html")
router.Use(cors.Default())
// static content
router.Static("/static", "../static")
router.GET("/", handlers.Home)
router.GET("/properties", handlers.PropertiesHandler)
// properties
router.GET("/properties/rootnodes", propertyTypesHandler.GetRootPropertyTypesGroups)
router.GET("/properties/:id/childs", propertyTypesHandler.GetPropertyTypesGroupDirectChildsById)
/*
router.GET("/products", handlers.ProductsHandler)
router.GET("/conditions", handlers.ConditionsHandler)
router.GET("/translations", handlers.TranslationsHandler)
*/
// import
router.POST("/importPropertyTypes", importHandler.ImportPropertyTypeGroups)
// test endpoint
router.GET("/test", Test)
// server
return HttpServer{
config: config,
router: router,
dbHandler: dbHandler,
config: config,
router: router,
dbHandler: dbHandler,
importHandler: importHandler,
importRepository: importRepository,
valueRepository: valueRepository,
propertyRepository: propertyRepository,
propertyTypeRepository: propertyTypeRepository,
propertyTypeGroupRepository: propertyTypeGroupRepository,
}
}
@@ -0,0 +1 @@
exit status 1
Binary file not shown.
@@ -0,0 +1,286 @@
[
{
"name": "X-CPQ",
"description": "Property Type Group for X-CPQ",
"property_types_Groups": [
{
"name": "electrical",
"description": "All electrical property types",
"property_types": [
{
"name": "Spannungsversorgung (V)",
"description": "Spannungsversorgung (V)",
"property": {
"name": "Spannungsversorgung (V)",
"description": "Spannungsversorgung (V)",
"values": [
{ "value": "220" },
{ "value": "230" }
]
}
},
{
"name": "Leistung (W)",
"description": "Leistung",
"property": {
"name": "Leistung (W)",
"description": "Leistung",
"values": [
{ "value": "0" },
{ "value": "140" },
{ "value": "130" },
{ "value": "120" },
{ "value": "110" },
{ "value": "100" },
{ "value": "90" },
{ "value": "80" },
{ "value": "70" },
{ "value": "60" },
{ "value": "50" },
{ "value": "28" },
{ "value": "26" },
{ "value": "24" },
{ "value": "22" },
{ "value": "20" }
]
}
},
{
"name": "Eingangsimpedanz (Ω)",
"description": "Wiederstand der Eingangsimpedanz",
"property": {
"name": "Eingangsimpedanz (Ω)",
"description": "Wiederstand der Eingangsimpedanz",
"values": [
{ "value": "10" }
]
}
},
{
"name": "Frequenzbereich (Hz‑kHz)",
"description": "Frequenzbereich (Hz‑kHz)",
"property": {
"name": "Frequenzbereich (Hz‑kHz)",
"description": "Frequenzbereich (Hz‑kHz)",
"values": [
{ "value": "87‑108" }
]
}
},
{
"name": "Signal‑Rausch‑Verhältnis (dB)",
"description": "Signal‑Rausch‑Verhältnis (dB)",
"property": {
"name": "Signal‑Rausch‑Verhältnis (dB)",
"description": "Signal‑Rausch‑Verhältnis (dB)",
"values": [
{ "value": "48" },
{ "value": "46" },
{ "value": "47" },
{ "value": "45" },
{ "value": "49" },
{ "value": "44" }
]
}
},
{
"name": "Anschlüsse",
"description": "Anschlüsse",
"property": {
"name": "Anschlüsse",
"description": "Anschlüsse",
"values": [
{ "value": "UKW+Bluetooth+DL" },
{ "value": "UKW+Wi‑Fi+DL" },
{ "value": "UKW+DL+Bluetooth" },
{ "value": "UKW+Bluetooth+Wi‑Fi" },
{ "value": "UKW+Wi‑Fi+DL" },
{ "value": "UKW+Wi‑Fi" },
{ "value": "UKW+Bluetooth" },
{ "value": "UKW+DL" },
{ "value": "UKW" }
]
}
},
{
"name": "Ausgangsimpedanz (Ω)",
"description": "Ausgangsimpedanz (Ω)",
"property": {
"name": "Ausgangsimpedanz (Ω)",
"description": "Ausgangsimpedanz (Ω)",
"values": [
{ "value": "75" }
]
}
}
]
},
{
"name": "mechanical",
"description": "All mechanical properties",
"property_types": [
{
"name": "Abmessungen (mm)",
"description": "All mechanical properties",
"property": {
"name": "Abmessungen (mm)",
"description": "All mechanical properties",
"values": [
{ "value": "158x88x33" },
{ "value": "310x210x110" },
{ "value": "160x90x35" },
{ "value": "170x100x42" },
{ "value": "150x80x30" },
{ "value": "155x85x32" },
{ "value": "165x95x38" },
{ "value": "305x205x105" },
{ "value": "172x102x44" },
{ "value": "340x240x140" },
{ "value": "420x320x140" },
{ "value": "162x92x36" },
{ "value": "300x200x100" },
{ "value": "168x98x40" },
{ "value": "315x215x115" },
{ "value": "325x225x125" },
{ "value": "415x315x135" },
{ "value": "320x220x120" },
{ "value": "335x235x135" },
{ "value": "330x230x130" },
{ "value": "400x300x120" },
{ "value": "405x305x125" },
{ "value": "345x245x145" },
{ "value": "295x245x135" },
{ "value": "410x310x130" },
{ "value": "290x240x130" },
{ "value": "285x235x125" },
{ "value": "280x230x120" },
{ "value": "275x225x115" },
{ "value": "270x220x110" },
{ "value": "265x215x105" },
{ "value": "255x205x95" },
{ "value": "260x210x100" },
{ "value": "250x200x90" },
{ "value": "445x345x165" },
{ "value": "440x340x160" },
{ "value": "435x335x155" },
{ "value": "430x330x150" },
{ "value": "425x325x145" }
]
},
{
"name": "Gewicht (kg)",
"description": "All mechanical properties",
"property": {
"name": "Gewicht (kg)",
"description": "All mechanical properties",
"values": [
{ "value": "3" },
{ "value": "6" },
{ "value": "4" },
{ "value": "2" }
]
}
},
{
"name": "Kapazität (kg)",
"description": "All mechanical properties",
"property": {
"name": "Kapazität (kg)",
"description": "All mechanical properties",
"values": [
{ "value": "0" }
]
}
},
{
"name": "Programms/Features",
"description": "All mechanical properties",
"property": {
"name": "Programms/Features",
"description": "All mechanical properties",
"values": []
}
},
{
"name": "Wasserverbrauch pro Zyklus (L)",
"description": "All mechanical properties",
"property": {
"name": "Wasserverbrauch pro Zyklus (L)",
"description": "All mechanical properties",
"values": []
}
},
{
"name": "Material Innenraum",
"description": "All mechanical properties",
"property": {
"name": "Material Innenraum",
"description": "All mechanical properties",
"values": []
}
},
{
"name": "Kapazität/Volumen (L)",
"description": "All mechanical properties",
"property": {
"name": "Kapazität/Volumen (L)",
"description": "All mechanical properties",
"values": []
}
},
{
"name": "Schleuderdrehzahl (U/min)",
"description": "All mechanical properties",
"property": {
"name": "Schleuderdrehzahl (U/min)",
"description": "All mechanical properties",
"values": []
}
}
]
},
{
"name": "other",
"description": "All other properties",
"property_types": [
{
"name": "Preis (USD)",
"description": "All other properties",
"property": {
"name": "Preis (USD)",
"description": "All other properties",
"values": []
}
},
{
"name": "Zusatzfunktionen",
"description": "All other properties",
"property": {
"name": "Zusatzfunktionen",
"description": "All other properties",
"values": []
}
},
{
"name": "Bedienungsart",
"description": "All other properties",
"property": {
"name": "Bedienungsart",
"description": "All other properties",
"values": []
}
},
{
"name": "Energieeffizienzklasse",
"description": "All other properties",
"property": {
"name": "Energieeffizienzklasse",
"description": "All other properties",
"values": []
}
}
]
}
]
}
]
@@ -0,0 +1,44 @@
package handlers
import (
"log"
"net/http"
"xcpq_editor/internal/models"
"xcpq_editor/internal/services"
"github.com/gin-gonic/gin"
)
type ImportHandler struct {
importService *services.Import_Service
}
func NewImportHandler(i *services.Import_Service) *ImportHandler {
return &ImportHandler{
importService: i,
}
}
func (h *ImportHandler) ImportPropertyTypeGroups(ctx *gin.Context) {
// Handle the import request here
var importData []models.Property_Types_Group
if err := ctx.ShouldBindJSON(&importData); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
for _, item := range importData {
log.Println("Importing property types group with ID:", item.Id)
log.Println("Anzahl Sub-Groups:", len(item.Property_Types_Groups))
err := h.importService.ImportPropertyTypesData(&item, nil)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
}
ctx.JSON(http.StatusOK, gin.H{
"message": "Import successful",
})
}
@@ -0,0 +1,67 @@
package handlers
import (
"log"
"net/http"
"strconv"
"xcpq_editor/internal/services"
"github.com/gin-gonic/gin"
)
type PropertyTypesHandler struct {
propertyTypeService *services.PropertyTypeService
}
func NewPropertyTypesHandler(propertyTypeService *services.PropertyTypeService) *PropertyTypesHandler {
return &PropertyTypesHandler{
propertyTypeService: propertyTypeService,
}
}
func (h *PropertyTypesHandler) GetRootPropertyTypesGroups(ctx *gin.Context) {
rootGroups, err := h.propertyTypeService.GetRootPropertyTypesGroups()
if rootGroups == nil {
ctx.JSON(http.StatusNotFound, gin.H{"error": "No root property types groups found"})
return
}
// If there was an error but rootGroups is not nil, we still want to return the data
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// execute template
log.Printf("Rendering root property types groups template with data")
ctx.HTML(http.StatusOK, "ptg_treeNode", rootGroups)
log.Printf("Rendered root property types groups template successfully")
}
func (h *PropertyTypesHandler) GetPropertyTypesGroupDirectChildsById(ctx *gin.Context) {
idParam := ctx.Param("id")
id, err := strconv.Atoi(idParam)
if err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
return
}
propertyTypesGroup, err := h.propertyTypeService.GetPropertyTypesGroupWithDirectChildsById(id)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
if propertyTypesGroup == nil {
ctx.JSON(http.StatusNotFound, gin.H{"error": "Property types group not found"})
return
}
log.Printf("Rendering direct child property types groups template for property types group with ID %d", id)
log.Printf("Direct child property types groups for property types group with ID %d: %v", id, propertyTypesGroup.Property_Types_Groups)
log.Printf("Direct child property types groups for property types with ID %d: %v", id, propertyTypesGroup.Property_Types)
// execute template
ctx.HTML(http.StatusOK, "ptg_treeNode", propertyTypesGroup.Property_Types_Groups)
}
@@ -0,0 +1,9 @@
package models
type Product_Group struct {
Id int `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Image_Url string `json:"image_url,omitempty"`
Properties []Property `json:"properties,omitempty"`
}
@@ -1,10 +1,13 @@
package models
type Property struct {
Id int
Name string
Description string
Image_Url string
Parent_Property *Property
Values []Value
Id int `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Image_Url string `json:"image_url,omitempty"`
//Property_Type *Property_Type `json:"property_type,omitempty"`
Parent_Property *Property `json:"parent_property,omitempty"`
Products_Group *Product_Group `json:"products_group,omitempty"`
Product *Product `json:"products,omitempty"`
Values []Value `json:"values,omitempty"`
}
@@ -1,9 +1,9 @@
package models
type Property_Type struct {
Id int
Name string
Description string
Image_Url string
Property Property
Id int `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Image_Url string `json:"image_url,omitempty"`
Property Property `json:"property"`
}
@@ -1,10 +1,10 @@
package models
type Property_Types_Group struct {
Id int
Name string
Description string
Image_Url string
Property_Types []Property_Type
Property_Types_Groups []Property_Types_Group
Id int `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Image_Url string `json:"image_url,omitempty"`
Property_Types []Property_Type `json:"property_types,omitempty"`
Property_Types_Groups []Property_Types_Group `json:"property_types_groups,omitempty"`
}
@@ -1,7 +1,7 @@
package models
type Value struct {
Id int
Value string
Image_Url string
Id int `json:"id,omitempty"`
Value string `json:"value"`
Image_Url string `json:"image_url,omitempty"`
}
@@ -13,7 +13,7 @@ type Import_Repository struct {
pr *Property_Repository
}
func NewImport_Repository(db *sql.DB, vr *Value_Repository, pt *Property_Type_Repository, ptg *Property_Types_Group_Repository, pr *Property_Repository) *Import_Repository {
func NewImportRepository(db *sql.DB, vr *Value_Repository, pt *Property_Type_Repository, ptg *Property_Types_Group_Repository, pr *Property_Repository) *Import_Repository {
return &Import_Repository{
db: db,
vr: vr,
@@ -2,6 +2,7 @@ package repositories
import (
"database/sql"
"log"
"xcpq_editor/internal/models"
)
@@ -45,8 +46,8 @@ func (pr *Property_Repository) CreateProperty(
parent_property_id = 0
}
query := `INSERT INTO properties (name, description, parent_property_id, property_type_id, product_id, image_url) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id`
err := pr.db.QueryRow(query, property.Name, property.Description, parent_property_id, property_type_id, product_id, property.image_url).Scan(&property.Id)
query := `INSERT INTO properties.properties (name, description, parent_property_id, property_type_id, products_id, image_url) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id`
err := pr.db.QueryRow(query, property.Name, property.Description, parent_property_id, property_type_id, product_id, property.Image_Url).Scan(&property.Id)
if err != nil {
return nil, err
}
@@ -65,18 +66,87 @@ func (pr *Property_Repository) CreateProperty(
product.Properties = append(product.Properties, *property)
}
for _, value := range property.Values {
v, err := pr.vr.CreateValueForPropertyId(property.Id, &value)
if err != nil {
return nil, err
}
value = *v
}
return property, nil
}
func (pr *Property_Repository) GetPropertyById(id int) (*models.Property, error) {
// Implement the logic to retrieve a property by its ID from the database
query := `SELECT id, name, description, parent_property_id, image_url FROM properties WHERE id = $1`
query := `SELECT id, name, description, parent_property_id, image_url FROM properties.properties WHERE id = $1`
property := &models.Property{}
log.Printf("Repository: Retrieving property with ID %d", id)
var parent_property_id int
err := pr.db.QueryRow(query, id).Scan(&property.Id, &property.Name, &property.Description, &parent_property_id, &property.image_url)
err := pr.db.QueryRow(query, id).Scan(&property.Id, &property.Name, &property.Description, &parent_property_id, &property.Image_Url)
if err != nil {
return nil, err
}
if parent_property_id != 0 {
parent_property, err := pr.GetPropertyById(parent_property_id)
if err == nil {
property.Parent_Property = parent_property
log.Printf("Repository: Appending parent property with ID %d to property with ID %d", parent_property.Id, property.Id)
}
} else {
property.Parent_Property = nil
}
valuePtrs, err := pr.vr.GetValuesFromPropertyId(property.Id)
if err != nil {
return property, err
}
property.Values = make([]models.Value, 0, len(valuePtrs))
for _, value := range valuePtrs {
if value != nil {
property.Values = append(property.Values, *value)
}
}
return property, nil
}
func (pr *Property_Repository) UpdateProperty(property *models.Property) error {
// Implement the logic to update an existing property in the database
query := `UPDATE properties.properties SET name=$1, description=$2, image_url=$3 WHERE id=$4`
_, err := pr.db.Exec(query, property.Name, property.Description, property.Image_Url, property.Id)
return err
}
func (pr *Property_Repository) DeleteProperty(id int) error {
// Implement the logic to delete a property from the database
// First, delete all values associated with the property
err := pr.vr.DeleteValuesFromPropertyId(id)
if err != nil {
return err
}
query := `DELETE FROM properties.properties WHERE id=$1`
_, err = pr.db.Exec(query, id)
return err
}
func (pr *Property_Repository) GetPropertyByPropertyType(property_type *models.Property_Type) (*models.Property, error) {
// Implement the logic to retrieve a property by its property type ID from the database
query := `SELECT id, name, description, parent_property_id, products_groups_id, products_id, image_url
FROM properties.properties
WHERE property_type_id = $1`
property := &models.Property{}
var parent_property_id int
var products_groups_id int
var products_id int
err := pr.db.QueryRow(query, property_type.Id).Scan(&property.Id, &property.Name, &property.Description, &parent_property_id, &products_groups_id, &products_id, &property.Image_Url)
if err != nil {
return nil, err
}
if parent_property_id != 0 {
parent_property, err := pr.GetPropertyById(parent_property_id)
if err == nil {
@@ -100,23 +170,3 @@ func (pr *Property_Repository) GetPropertyById(id int) (*models.Property, error)
return property, nil
}
func (pr *Property_Repository) UpdateProperty(property *models.Property) error {
// Implement the logic to update an existing property in the database
query := `UPDATE properties SET name=$1, description=$2, image_url=$3 WHERE id=$4`
_, err := pr.db.Exec(query, property.Name, property.Description, property.image_url, property.Id)
return err
}
func (pr *Property_Repository) DeleteProperty(id int) error {
// Implement the logic to delete a property from the database
// First, delete all values associated with the property
err := pr.vr.DeleteValuesFromPropertyId(id)
if err != nil {
return err
}
query := `DELETE FROM properties WHERE id=$1`
_, err = pr.db.Exec(query, id)
return err
}
@@ -2,6 +2,7 @@ package repositories
import (
"database/sql"
"log"
"xcpq_editor/internal/models"
)
@@ -29,8 +30,8 @@ func (ptr *Property_Type_Repository) CreatePropertyType(
} else {
property_type_group_id = 0
}
query := `INSERT INTO property_types (name, description, property_type_group_id, image_url) VALUES ($1, $2, $3, $4) RETURNING id`
err := ptr.db.QueryRow(query, property_type.Name, property_type.Description, property_type_group_id, property_type.image_url).Scan(&property_type.Id)
query := `INSERT INTO properties.property_types (name, description, property_types_groups_id, image_url) VALUES ($1, $2, $3, $4) RETURNING id`
err := ptr.db.QueryRow(query, property_type.Name, property_type.Description, property_type_group_id, property_type.Image_Url).Scan(&property_type.Id)
if err != nil {
return nil, err
}
@@ -50,27 +51,32 @@ func (ptr *Property_Type_Repository) CreatePropertyType(
func (ptr *Property_Type_Repository) GetPropertyTypeById(id int) (*models.Property_Type, error) {
// Implement the logic to retrieve a property type by its ID from the database
query := "SELECT id, name, description, image_url FROM property_types WHERE id = $1"
query := "SELECT id, name, description, image_url FROM properties.property_types WHERE id = $1"
property_type := &models.Property_Type{}
err := ptr.db.QueryRow(query, id).Scan(&property_type.Id, &property_type.Name, &property_type.Description, &property_type.image_url)
err := ptr.db.QueryRow(query, id).Scan(&property_type.Id, &property_type.Name, &property_type.Description, &property_type.Image_Url)
if err != nil {
return nil, err
}
property, err := ptr.pr.GetPropertyById(property_type.Id)
log.Printf("Repository: Retrieved property type with ID %d", property_type.Id)
property, err := ptr.pr.GetPropertyByPropertyType(property_type)
if err != nil {
return nil, err
}
log.Printf("Repository: Retrieved property with ID %d for property type with ID %d", property.Id, property_type.Id)
property_type.Property = *property
return property_type, nil
}
func (ptr *Property_Type_Repository) UpdatePropertyType(property_type *models.Property_Type) error {
// Implement the logic to update the label/description of an existing property type
query := `UPDATE property_types SET name=$1, description=$2, image_url=$3 WHERE id=$4`
_, err := ptr.db.Exec(query, property_type.Name, property_type.Description, property_type.image_url, property_type.Id)
query := `UPDATE properties.property_types SET name=$1, description=$2, image_url=$3 WHERE id=$4`
_, err := ptr.db.Exec(query, property_type.Name, property_type.Description, property_type.Image_Url, property_type.Id)
return err
}
func (ptr *Property_Type_Repository) DeletePropertyTypeById(id int) error {
// Implement the logic to delete a property type from the database
query := `DELETE FROM property_types WHERE id=$1`
query := `DELETE FROM properties.property_types WHERE id=$1`
_, err := ptr.db.Exec(query, id)
return err
}
@@ -2,6 +2,7 @@ package repositories
import (
"database/sql"
"log"
"xcpq_editor/internal/models"
)
@@ -25,10 +26,10 @@ func (ptrg *Property_Types_Group_Repository) CreatePropertyTypesGroup(property_t
parentPropertyTypeGroup.Property_Types_Groups = append(parentPropertyTypeGroup.Property_Types_Groups, *property_types_group)
} else {
parentId = 0 // or any other value that indicates no parent
property_types_group.Property_Types_Groups = []models.Property_Types_Group{}
property_types_group.Property_Types = []models.Property_Type{}
//property_types_group.Property_Types_Groups = []models.Property_Types_Group{}
//property_types_group.Property_Types = []models.Property_Type{}
}
query := `INSERT INTO property_types_groups (name, description, image_url, parent_property_type_group) VALUES ($1, $2, $3, $4) RETURNING id`
query := `INSERT INTO properties.property_types_groups (name, description, image_url, parent_property_type_group_id) VALUES ($1, $2, $3, $4) RETURNING id`
err := ptrg.db.QueryRow(query, property_types_group.Name, property_types_group.Description, property_types_group.Image_Url, parentId).Scan(&property_types_group.Id)
if err != nil {
return nil, err
@@ -38,15 +39,48 @@ func (ptrg *Property_Types_Group_Repository) CreatePropertyTypesGroup(property_t
func (ptrg *Property_Types_Group_Repository) GetPropertyTypesGroupById(id int) (*models.Property_Types_Group, error) {
// Implement the logic to retrieve a property types group by its ID from the database
query := "SELECT id, name, description, image_url FROM property_types_groups WHERE id = $1"
query := "SELECT id, name, description, image_url FROM properties.property_types_groups WHERE id = $1"
property_types_group := &models.Property_Types_Group{}
err := ptrg.db.QueryRow(query, id).Scan(&property_types_group.Id, &property_types_group.Name, &property_types_group.Description, &property_types_group.Image_Url)
if err != nil {
return nil, err
}
// get all property
queryProperties := "SELECT id FROM properties.property_types WHERE property_types_groups_id = $1"
rowsProperties, err := ptrg.db.Query(queryProperties, id)
if err != nil {
return nil, err
}
defer rowsProperties.Close()
for rowsProperties.Next() {
id := 0
err := rowsProperties.Scan(&id)
if err != nil {
return nil, err
}
log.Printf("Retrieved property type with ID %d for property types group with ID %d", id, property_types_group.Id)
property, err := ptrg.property_Type_Repository.GetPropertyTypeById(id)
if err != nil {
return nil, err
}
log.Printf("Appending property type with ID %d to property types group with ID %d", property.Id, property_types_group.Id)
property_types_group.Property_Types = append(property_types_group.Property_Types, *property)
}
return property_types_group, nil
}
func (ptrg *Property_Types_Group_Repository) GetPropertyTypesGroupWithDirectChildsById(id int) (*models.Property_Types_Group, error) {
// Implement the logic to retrieve a property types group by its ID from the database
property_types_group, err := ptrg.GetPropertyTypesGroupById(id)
if err != nil {
return nil, err
}
// get all childs
queryChilds := "SELECT id FROM property_types_groups WHERE parent_property_type_group = $1"
queryChilds := "SELECT id FROM properties.property_types_groups WHERE parent_property_type_group_id = $1"
rows, err := ptrg.db.Query(queryChilds, id)
if err != nil {
return nil, err
@@ -66,14 +100,46 @@ func (ptrg *Property_Types_Group_Repository) GetPropertyTypesGroupById(id int) (
property_types_group.Property_Types_Groups = append(property_types_group.Property_Types_Groups, *child)
}
return property_types_group, nil
}
func (ptrg *Property_Types_Group_Repository) GetPropertyTypesGroupDirectChildGroupsById(id int) ([]*models.Property_Types_Group, error) {
// get all childs
queryChilds := "SELECT id FROM properties.property_types_groups WHERE parent_property_type_group_id = $1"
rows, err := ptrg.db.Query(queryChilds, id)
if err != nil {
return nil, err
}
defer rows.Close()
property_Types_Groups := []*models.Property_Types_Group{}
for rows.Next() {
id := 0
err := rows.Scan(&id)
if err != nil {
return nil, err
}
child, err := ptrg.GetPropertyTypesGroupById(id)
if err != nil {
return nil, err
}
property_Types_Groups = append(property_Types_Groups, child)
}
return property_Types_Groups, nil
}
func (ptrg *Property_Types_Group_Repository) GetPropertyTypesGroupPropertyTypesById(id int) ([]*models.Property_Type, error) {
// get all property
queryProperties := "SELECT id FROM property_types WHERE property_types_group = $1"
queryProperties := "SELECT id FROM properties.property_types WHERE property_types_groups_id = $1"
rowsProperties, err := ptrg.db.Query(queryProperties, id)
if err != nil {
return nil, err
}
defer rowsProperties.Close()
property_Types := []*models.Property_Type{}
for rowsProperties.Next() {
id := 0
err := rowsProperties.Scan(&id)
@@ -84,26 +150,25 @@ func (ptrg *Property_Types_Group_Repository) GetPropertyTypesGroupById(id int) (
if err != nil {
return nil, err
}
property_types_group.Property_Types = append(property_types_group.Property_Types, *property)
property_Types = append(property_Types, property)
}
return property_types_group, nil
return property_Types, nil
}
func (ptrg *Property_Types_Group_Repository) UpdatePropertyTypesGroup(property_types_group *models.Property_Types_Group) error {
// Implement the logic to update the label/description of an existing property types group
query := `UPDATE property_types_groups SET name=$1, description=$2, image_url=$3 WHERE id=$4`
query := `UPDATE properties.property_types_groups SET name=$1, description=$2, image_url=$3 WHERE id=$4`
_, err := ptrg.db.Exec(query, property_types_group.Name, property_types_group.Description, property_types_group.Image_Url, property_types_group.Id)
return err
}
func (ptrg *Property_Types_Group_Repository) DeletePropertyTypesGroup(id int) error {
// Implement the logic to delete a property types group from the database
query := `DELETE FROM property_types_groups WHERE id=$1`
query := `DELETE FROM properties.property_types_groups WHERE id=$1`
_, err := ptrg.db.Exec(query, id)
// delete all child property types groups
queryChilds := "SELECT id FROM property_types_groups WHERE parent_property_type_group = $1"
queryChilds := "SELECT id FROM properties.property_types_groups WHERE parent_property_type_group_id = $1"
rows, err := ptrg.db.Query(queryChilds, id)
if err != nil {
return err
@@ -123,7 +188,7 @@ func (ptrg *Property_Types_Group_Repository) DeletePropertyTypesGroup(id int) er
}
// delete all property types in this group
queryProperties := "SELECT id FROM property_types WHERE property_types_group = $1"
queryProperties := "SELECT id FROM properties.property_types WHERE property_types_groups_id = $1"
rowsProperties, err := ptrg.db.Query(queryProperties, id)
if err != nil {
return err
@@ -144,3 +209,31 @@ func (ptrg *Property_Types_Group_Repository) DeletePropertyTypesGroup(id int) er
return err
}
func (ptrg *Property_Types_Group_Repository) GetRootPropertyTypesGroups() ([]*models.Property_Types_Group, error) {
query := "SELECT id FROM properties.property_types_groups WHERE parent_property_type_group_id = 0"
rows, err := ptrg.db.Query(query)
if err != nil {
log.Printf("Error querying root property types groups: %v", err)
return nil, err
}
defer rows.Close()
var rootGroups []*models.Property_Types_Group
for rows.Next() {
id := 0
err := rows.Scan(&id)
if err != nil {
return nil, err
}
log.Printf("Loading root property types group with ID: %d", id)
group, err := ptrg.GetPropertyTypesGroupById(id)
if err != nil {
log.Printf("Error loading root property types group with ID: %d: %v", id, err)
return nil, err
}
rootGroups = append(rootGroups, group)
}
log.Printf("Loaded %d root property types groups", len(rootGroups))
return rootGroups, nil
}
@@ -17,7 +17,7 @@ func NewValueRepository(db *sql.DB) *Value_Repository {
func (vr *Value_Repository) CreateValueForPropertyId(propertyId int, value *models.Value) (*models.Value, error) {
// Implement the logic to create a new value for the given propertyId in the database
query := `INSERT INTO values (propertyid, value, image_url) VALUES ($1, $2, $3) RETURNING id`
query := `INSERT INTO properties.values (properties_id, value, image_url) VALUES ($1, $2, $3) RETURNING id`
err := vr.db.QueryRow(query, propertyId, value.Value, value.Image_Url).Scan(&value.Id)
if err != nil {
return nil, err
@@ -27,21 +27,21 @@ func (vr *Value_Repository) CreateValueForPropertyId(propertyId int, value *mode
func (vr *Value_Repository) DeleteValueFromPropertyId(valueId int, propertyId int) error {
// Implement the logic to delete the value from the database for the given valueId and propertyId
query := `DELETE FROM values WHERE id=$1 AND propertyid=$2`
query := `DELETE FROM properties.values WHERE id=$1 AND properties_id=$2`
_, err := vr.db.Exec(query, valueId, propertyId)
return err
}
func (vr *Value_Repository) UpdateValue(value *models.Value) error {
// Implement the logic to update the value in the database for the given valueId
query := `UPDATE values SET value=$1, image_url=$2 WHERE id=$3`
query := `UPDATE properties.values SET value=$1, image_url=$2 WHERE id=$3`
_, err := vr.db.Exec(query, value.Value, value.Image_Url, value.Id)
return err
}
func (vr *Value_Repository) GetValue(id int) (*models.Value, error) {
// Implement the logic to retrieve a value by its ID from the database
query := "SELECT id, value, image_url FROM values WHERE id = $1"
query := "SELECT id, value, image_url FROM properties.values WHERE id = $1"
row := vr.db.QueryRow(query, id)
value := &models.Value{}
err := row.Scan(&value.Id, &value.Value, &value.Image_Url)
@@ -53,14 +53,14 @@ func (vr *Value_Repository) GetValue(id int) (*models.Value, error) {
func (vr *Value_Repository) DeleteValuesFromPropertyId(propertyId int) error {
// Implement the logic to delete all values from the database for the given propertyId
query := `DELETE FROM values WHERE propertyid=$1`
query := `DELETE FROM properties.values WHERE properties_id=$1`
_, err := vr.db.Exec(query, propertyId)
return err
}
func (vr *Value_Repository) GetValuesFromPropertyId(propertyId int) ([]*models.Value, error) {
// Implement the logic to retrieve all values from the database for the given propertyId
query := `SELECT id, value, image_url FROM values WHERE propertyid=$1`
query := `SELECT id, value, image_url FROM properties.values WHERE properties_id=$1`
rows, err := vr.db.Query(query, propertyId)
if err != nil {
return nil, err
@@ -9,7 +9,7 @@ type Import_Service struct {
importRepository *repositories.Import_Repository
}
func NewImport_Service(importRepository *repositories.Import_Repository) *Import_Service {
func NewImportService(importRepository *repositories.Import_Repository) *Import_Service {
return &Import_Service{
importRepository: importRepository,
}
@@ -0,0 +1,63 @@
package services
import (
"log"
"xcpq_editor/internal/models"
"xcpq_editor/internal/repositories"
)
type PropertyTypeService struct {
// Add any dependencies or fields needed for the service here
property_Types_Repository *repositories.Property_Type_Repository
property_Types_Groups_Repository *repositories.Property_Types_Group_Repository
}
func NewPropertyTypeService(propertyTypesRepo *repositories.Property_Type_Repository, propertyTypesGroupsRepo *repositories.Property_Types_Group_Repository) *PropertyTypeService {
return &PropertyTypeService{
property_Types_Repository: propertyTypesRepo,
property_Types_Groups_Repository: propertyTypesGroupsRepo,
}
}
func (s *PropertyTypeService) GetRootPropertyTypesGroups() ([]*models.Property_Types_Group, error) {
var rootGroups []*models.Property_Types_Group
var err error
rootGroupsTemp, err := s.property_Types_Groups_Repository.GetRootPropertyTypesGroups()
if err != nil {
return nil, err
}
for i := range rootGroupsTemp {
rootGroups = append(rootGroups, rootGroupsTemp[i])
}
log.Printf("Service Loaded %d root property types groups", len(rootGroups))
return rootGroups, nil
}
func (s *PropertyTypeService) GetPropertyTypesGroupWithDirectChildsById(id int) (*models.Property_Types_Group, error) {
propertyTypesGroup, err := s.property_Types_Groups_Repository.GetPropertyTypesGroupWithDirectChildsById(id)
if err != nil {
return nil, err
}
log.Printf("Service Loaded property types group with ID %d", propertyTypesGroup.Id)
return propertyTypesGroup, nil
}
func (s *PropertyTypeService) GetPropertyTypesGroupDirectChildGroupsById(id int) ([]*models.Property_Types_Group, error) {
childGroups, err := s.property_Types_Groups_Repository.GetPropertyTypesGroupDirectChildGroupsById(id)
if err != nil {
return nil, err
}
log.Printf("Service Loaded %d direct child property types groups for property types group with ID %d", len(childGroups), id)
return childGroups, nil
}
func (s *PropertyTypeService) GetPropertyTypesGroupPropertyTypesById(id int) ([]*models.Property_Type, error) {
propertyTypes, err := s.property_Types_Groups_Repository.GetPropertyTypesGroupPropertyTypesById(id)
if err != nil {
return nil, err
}
log.Printf("Service Loaded %d property types for property types group with ID %d", len(propertyTypes), id)
return propertyTypes, nil
}
@@ -1,4 +1,4 @@
{{define "footer"}}
<!-- Footer content can be added here -->
<p>&copy; 2026 Simply CPQ</p>
<p>&copy; 2026 Simply CPQ by Dr. Thomas Sindt</p>
{{end}}
@@ -6,6 +6,17 @@
<div class="editor-container">
<section class="editor-view">
<h3>Property Type Groups</h3>
<ul class="node mt-16" hx-get="/properties/rootnodes" hx-trigger="click" hx-target="#PropertyTypeGroupList" hx-swap="outerHTML">
<details close>
<summary>
X-CPQ-Eigenschaften
</summary>
<div id="PropertyTypeGroupList">
<!-- Property type groups will be dynamically loaded here -->
</div>
</details>
</ul>
<!--
<ul class="node mt-16">
<details open>
<summary>
@@ -47,6 +58,7 @@
</ul>
</details>
</ul>
-->
</section>
<section class="editor-view">
<section id="PropertyTypeGroupData">
@@ -0,0 +1,21 @@
{{define "ptg_treeNode"}}
{{range .}}
<ul class="node" hx-get="/properties/{{.Id}}/childs" hx-trigger="click" hx-target="#node-{{.Id}}" hx-swap="outerHTML">
<details closed>
<summary>
{{.Name}}
</summary>
<div id="node-{{.Id}}">Keine Informationen vorhanden
</div>
<!--
{{template "ptg_treeNode" .Property_Types_Groups}}
<ul class="node">
{{range .Property_Types}}
<li>{{.Name}}</li>
{{end}}
</ul>
-->
</details>
</ul>
{{end}}
{{end}}
@@ -0,0 +1,18 @@
{{define "ptg_treeNode"}}
{{- range .}}
<ul class="node" hx-get="/properties/{{.Id}}/childs" hx-trigger="click" hx-target="#node-{{.Id}}" hx-swap="outerHTML">
<details closed>
<summary>
{{.Name}}
</summary>
<div id="node-{{.Id}}">Keine Informationen vorhanden
</div>
<ul class="node">
{{range .Property_Types}}
<li>{{.Name}}</li>
{{end}}
</ul>
</details>
</ul>
{{- end}}
{{end}}
+329
View File
@@ -0,0 +1,329 @@
--
-- PostgreSQL database dump
--
\restrict QLwsCbodiNlV3JQJRfmAVxaxLqILLV0Fv9uJeVlzDiu4p6FKUIYquZWE1PbaK7o
-- Dumped from database version 18.4 (Debian 18.4-1.pgdg13+1)
-- Dumped by pg_dump version 18.4
-- Started on 2026-09-14 14:31:10
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- TOC entry 6 (class 2615 OID 20689)
-- Name: properties; Type: SCHEMA; Schema: -; Owner: tsindt
--
CREATE SCHEMA properties;
ALTER SCHEMA properties OWNER TO tsindt;
--
-- TOC entry 3481 (class 0 OID 0)
-- Dependencies: 6
-- Name: SCHEMA properties; Type: COMMENT; Schema: -; Owner: tsindt
--
COMMENT ON SCHEMA properties IS 'Alle Tabellen, die mit Properties und Values zu tun haben.';
--
-- TOC entry 220 (class 1259 OID 20691)
-- Name: properties_id_seq; Type: SEQUENCE; Schema: properties; Owner: tsindt
--
CREATE SEQUENCE properties.properties_id_seq
START WITH 1000000
INCREMENT BY 1
MINVALUE 1000000
MAXVALUE 4999999
CACHE 1;
ALTER SEQUENCE properties.properties_id_seq OWNER TO tsindt;
--
-- TOC entry 3482 (class 0 OID 0)
-- Dependencies: 220
-- Name: SEQUENCE properties_id_seq; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON SEQUENCE properties.properties_id_seq IS 'Zähler für property und value IDs ';
SET default_tablespace = '';
SET default_table_access_method = heap;
--
-- TOC entry 223 (class 1259 OID 20722)
-- Name: properties; Type: TABLE; Schema: properties; Owner: tsindt
--
CREATE TABLE properties.properties (
id bigint DEFAULT nextval('properties.properties_id_seq'::regclass) NOT NULL,
name text,
description text,
parent_property_id bigint DEFAULT 0 NOT NULL,
property_type_id bigint NOT NULL,
products_groups_id bigint DEFAULT 0 NOT NULL,
products_id bigint DEFAULT 0 NOT NULL,
image_url text DEFAULT 'https://www.thomas-sindt.de/img/properties_group.svg'::text
);
ALTER TABLE properties.properties OWNER TO tsindt;
--
-- TOC entry 3483 (class 0 OID 0)
-- Dependencies: 223
-- Name: TABLE properties; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON TABLE properties.properties IS 'Eigenschaften, die Listen von Werten enthalten und eine Information, von welchem property sich dieses Property ableitet. Ist parent_property_id = 0, dann ist dieses ein Root-Property zu dem referenzierten PropertyType.';
--
-- TOC entry 3484 (class 0 OID 0)
-- Dependencies: 223
-- Name: COLUMN properties.name; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON COLUMN properties.properties.name IS 'Der Name sollte derselbe sein, wie der referenzierte Property Type.';
--
-- TOC entry 3485 (class 0 OID 0)
-- Dependencies: 223
-- Name: COLUMN properties.products_groups_id; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON COLUMN properties.properties.products_groups_id IS 'Referenziert auf dieProduktgruppe, zu dem dieses Property gehört. Wenn es zu keiner Produktgruppe gehört ist diese referenz = 0';
--
-- TOC entry 3486 (class 0 OID 0)
-- Dependencies: 223
-- Name: COLUMN properties.products_id; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON COLUMN properties.properties.products_id IS 'Referenziert auf das Produkt, zu dem dieses Property gehört. Wenn es zu keinem Produkt gehört ist diese referenz = 0';
--
-- TOC entry 222 (class 1259 OID 20707)
-- Name: property_types; Type: TABLE; Schema: properties; Owner: tsindt
--
CREATE TABLE properties.property_types (
id bigint DEFAULT nextval('properties.properties_id_seq'::regclass) NOT NULL,
name text,
description text,
property_types_groups_id bigint NOT NULL,
image_url text DEFAULT 'https://www.thomas-sindt.de/img/category.svg'::text
);
ALTER TABLE properties.property_types OWNER TO tsindt;
--
-- TOC entry 3487 (class 0 OID 0)
-- Dependencies: 222
-- Name: TABLE property_types; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON TABLE properties.property_types IS 'Definition von properties';
--
-- TOC entry 221 (class 1259 OID 20698)
-- Name: property_types_groups; Type: TABLE; Schema: properties; Owner: tsindt
--
CREATE TABLE properties.property_types_groups (
id bigint DEFAULT nextval('properties.properties_id_seq'::regclass) CONSTRAINT property_types_group_id_not_null NOT NULL,
name text,
description text,
parent_property_type_group_id bigint,
image_url text DEFAULT 'https://thomas-sindt/img/category.svg'::text
);
ALTER TABLE properties.property_types_groups OWNER TO tsindt;
--
-- TOC entry 3488 (class 0 OID 0)
-- Dependencies: 221
-- Name: TABLE property_types_groups; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON TABLE properties.property_types_groups IS 'Baumstruktur zur Organisation von Property types
Wenn parent_property_types_group = 0, dann ist diese Gruppe eine Rootgruppe.';
--
-- TOC entry 224 (class 1259 OID 20743)
-- Name: values; Type: TABLE; Schema: properties; Owner: tsindt
--
CREATE TABLE properties."values" (
id bigint DEFAULT nextval('properties.properties_id_seq'::regclass) NOT NULL,
value text,
properties_id bigint NOT NULL,
image_url text DEFAULT 'https://www.thomas-sindt.de/img/property.svg'::text
);
ALTER TABLE properties."values" OWNER TO tsindt;
--
-- TOC entry 3474 (class 0 OID 20722)
-- Dependencies: 223
-- Data for Name: properties; Type: TABLE DATA; Schema: properties; Owner: tsindt
--
COPY properties.properties (id, name, description, parent_property_id, property_type_id, products_groups_id, products_id, image_url) FROM stdin;
\.
--
-- TOC entry 3473 (class 0 OID 20707)
-- Dependencies: 222
-- Data for Name: property_types; Type: TABLE DATA; Schema: properties; Owner: tsindt
--
COPY properties.property_types (id, name, description, property_types_groups_id, image_url) FROM stdin;
\.
--
-- TOC entry 3472 (class 0 OID 20698)
-- Dependencies: 221
-- Data for Name: property_types_groups; Type: TABLE DATA; Schema: properties; Owner: tsindt
--
COPY properties.property_types_groups (id, name, description, parent_property_type_group_id, image_url) FROM stdin;
\.
--
-- TOC entry 3475 (class 0 OID 20743)
-- Dependencies: 224
-- Data for Name: values; Type: TABLE DATA; Schema: properties; Owner: tsindt
--
COPY properties."values" (id, value, properties_id, image_url) FROM stdin;
\.
--
-- TOC entry 3489 (class 0 OID 0)
-- Dependencies: 220
-- Name: properties_id_seq; Type: SEQUENCE SET; Schema: properties; Owner: tsindt
--
SELECT pg_catalog.setval('properties.properties_id_seq', 1000000, false);
--
-- TOC entry 3318 (class 2606 OID 20733)
-- Name: properties properties_pkey; Type: CONSTRAINT; Schema: properties; Owner: tsindt
--
ALTER TABLE ONLY properties.properties
ADD CONSTRAINT properties_pkey PRIMARY KEY (id);
--
-- TOC entry 3314 (class 2606 OID 20706)
-- Name: property_types_groups property_types_group_pkey; Type: CONSTRAINT; Schema: properties; Owner: tsindt
--
ALTER TABLE ONLY properties.property_types_groups
ADD CONSTRAINT property_types_group_pkey PRIMARY KEY (id);
--
-- TOC entry 3316 (class 2606 OID 20716)
-- Name: property_types property_types_pkey; Type: CONSTRAINT; Schema: properties; Owner: tsindt
--
ALTER TABLE ONLY properties.property_types
ADD CONSTRAINT property_types_pkey PRIMARY KEY (id);
--
-- TOC entry 3320 (class 2606 OID 20752)
-- Name: values values_pkey; Type: CONSTRAINT; Schema: properties; Owner: tsindt
--
ALTER TABLE ONLY properties."values"
ADD CONSTRAINT values_pkey PRIMARY KEY (id);
--
-- TOC entry 3322 (class 2606 OID 20734)
-- Name: properties parent_property_type_id_fk; Type: FK CONSTRAINT; Schema: properties; Owner: tsindt
--
ALTER TABLE ONLY properties.properties
ADD CONSTRAINT parent_property_type_id_fk FOREIGN KEY (property_type_id) REFERENCES properties.property_types(id);
--
-- TOC entry 3490 (class 0 OID 0)
-- Dependencies: 3322
-- Name: CONSTRAINT parent_property_type_id_fk ON properties; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON CONSTRAINT parent_property_type_id_fk ON properties.properties IS 'Verweißt auf den Property Type dieses Properties';
--
-- TOC entry 3323 (class 2606 OID 20753)
-- Name: values properties_id_fk; Type: FK CONSTRAINT; Schema: properties; Owner: tsindt
--
ALTER TABLE ONLY properties."values"
ADD CONSTRAINT properties_id_fk FOREIGN KEY (properties_id) REFERENCES properties.properties(id);
--
-- TOC entry 3321 (class 2606 OID 20717)
-- Name: property_types property_types_groups_id_fk; Type: FK CONSTRAINT; Schema: properties; Owner: tsindt
--
ALTER TABLE ONLY properties.property_types
ADD CONSTRAINT property_types_groups_id_fk FOREIGN KEY (property_types_groups_id) REFERENCES properties.property_types_groups(id);
--
-- TOC entry 3491 (class 0 OID 0)
-- Dependencies: 3321
-- Name: CONSTRAINT property_types_groups_id_fk ON property_types; Type: COMMENT; Schema: properties; Owner: tsindt
--
COMMENT ON CONSTRAINT property_types_groups_id_fk ON properties.property_types IS 'Referenz auf die Property Type Gruppe, zu der dieser Property Type gehört.';
-- Completed on 2026-09-14 14:31:11
--
-- PostgreSQL database dump complete
--
\unrestrict QLwsCbodiNlV3JQJRfmAVxaxLqILLV0Fv9uJeVlzDiu4p6FKUIYquZWE1PbaK7o