diff --git a/buildtime/server/README.md b/buildtime/server/README.md index 7bc9bbe10..a239d55ac 100644 --- a/buildtime/server/README.md +++ b/buildtime/server/README.md @@ -258,4 +258,57 @@ Wenn Daten zurückkommen, so wie hier im Beispiel, dann werden sie im *"data"* T } ``` -### Value und Property Funktionen \ No newline at end of file +### Value und Property Funktionen + +#### Datentypen als JSON Beispiele: + +```json +// PropertyType +{ + "id": 1000003, + "label": "Colour", + "description": "System wide colors", + "propertyTypeGroupId": 100002 +} +``` + +```json +// Property +{ + "label": "Colour", + "description": "System wide colors", + "propertyTypeId": 1000003, + "productId": 0, + "productGroupId": 0 +} +``` + +```json +// Value +{ + "id": 1000003, + "label": "Red", + "description": "Color Red", + "propertyId": 100003 +} +``` + +```json +// ProductGroup +{ + "id": 1000003, + "label": "Red", + "description": "Color Red", + "propertyId": 100003 +} +``` + +```json +// Product +{ + "id": 1000003, + "label": "Red", + "description": "Color Red", + "propertyId": 100003 +} +``` \ No newline at end of file diff --git a/buildtime/server/SimplyCPQ.json b/buildtime/server/SimplyCPQ.json index 1b3f72f98..b38635cd8 100644 --- a/buildtime/server/SimplyCPQ.json +++ b/buildtime/server/SimplyCPQ.json @@ -23,13 +23,244 @@ "requestVariables": [], "responses": {}, "description": null + }, + { + "v": "17", + "name": "GetPropertyTypeGroup by ID", + "method": "GET", + "endpoint": "http://localhost:8088/getPropertyTypeGroup/1000001", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": null, + "body": null + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "name": "GetPropertyType by ParentGroupID", + "method": "GET", + "endpoint": "http://localhost:8088/getPropertyTypeGroupsByParentId/1000000", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": null, + "body": null + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "name": "create PropertyType", + "method": "POST", + "endpoint": "http://localhost:8088/createPropertyType", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": "application/json", + "body": "{\n \"label\": \"color\",\n \"description\": \"Definition des möglichen Farben\",\n \"propertyTypeGroupId\": 1000001\n}" + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "name": "Update PropertyType", + "method": "PUT", + "endpoint": "http://localhost:8088/updatePropertyType", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": "application/json", + "body": "{\n \"id\": 1000008,\n \"label\": \"Colour\",\n \"description\": \"System wide colors\",\n \"propertyTypeGroupId\": 100002\n}\n" + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "name": "getProertyType by id", + "method": "GET", + "endpoint": "http://localhost:8088/getPropertyType/1000003", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": null, + "body": null + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "name": "createValueFor PropertyType", + "method": "POST", + "endpoint": "http://localhost:8088/createValueForPropertyTypeId/1000003", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": "application/json", + "body": "{ \n \"label\": \"Red\",\n \"description\": \"Color Red\",\n \"propertyId\": 100003\n}" + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "name": "getValuesFromPropertyType", + "method": "GET", + "endpoint": "http://localhost:8088/getValuesFromPropertyTypeId/1000003", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": null, + "body": null + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "name": "createProductGroup", + "method": "POST", + "endpoint": "http://localhost:8088/createProductGroup", + "params": [], + "headers": [], + "preRequestScript": "", + "testScript": "", + "auth": { + "authType": "inherit", + "authActive": true + }, + "body": { + "contentType": "application/json", + "body": "{ \n \"label\": \"Catalog\",\n \"description\": \"Product catalog\",\n \"parentGroupId\": 1000007\n}" + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "endpoint": "http://localhost:8088/createPropertyToProductGroupId/1000010/1000028", + "name": "create Property from Property Type in Product Group", + "params": [], + "headers": [], + "method": "GET", + "auth": { + "authType": "inherit", + "authActive": true + }, + "preRequestScript": "", + "testScript": "", + "body": { + "contentType": null, + "body": null + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "endpoint": "http://localhost:8088/deleteValueFromPropertyId/1000036/1000033", + "name": "Delete value from property", + "params": [], + "headers": [], + "method": "DELETE", + "auth": { + "authType": "inherit", + "authActive": true + }, + "preRequestScript": "", + "testScript": "", + "body": { + "contentType": null, + "body": null + }, + "requestVariables": [], + "responses": {}, + "description": null + }, + { + "v": "17", + "endpoint": "https://echo.hoppscotch.io", + "name": "Test", + "params": [], + "headers": [], + "method": "GET", + "auth": { + "authType": "inherit", + "authActive": true + }, + "preRequestScript": "", + "testScript": "", + "body": { + "contentType": null, + "body": null + }, + "requestVariables": [], + "responses": {}, + "description": null } ], - "headers": [], "auth": { "authType": "none", "authActive": true }, + "headers": [], "variables": [], "description": "", "preRequestScript": "", diff --git a/buildtime/server/controller/productGroupController.go b/buildtime/server/controller/productGroupController.go index 072260007..f773cfff9 100644 --- a/buildtime/server/controller/productGroupController.go +++ b/buildtime/server/controller/productGroupController.go @@ -1,6 +1,7 @@ package controller import ( + "log" "net/http" "simplycpq/models" @@ -141,22 +142,25 @@ func (pgc *ProductGroupController) DeletePropertyFromProductGroupId(c *gin.Conte } func (pgc *ProductGroupController) CreatePropertyToProductGroupId(c *gin.Context) { - var property models.Property - if err := c.ShouldBindJSON(&property); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - productGroupId, err := strconv.Atoi(c.Param("productGroupId")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid product group ID"}) return } - property2, err := pgc.productGroupService.CreatePropertyToProductGroupId(productGroupId, &property) + log.Println("ProductGroupId:", productGroupId) + log.Println("PropertyTypeId:", c.Param("propertyTypeId")) + + propertyTypeId, err := strconv.Atoi(c.Param("propertyTypeId")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid property type ID"}) + return + } + + property, err := pgc.valueService.CreatePropertyFromPropertyTypeId(propertyTypeId, productGroupId, 0) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - c.JSON(http.StatusOK, gin.H{"message": "Property created", "data": property2}) + c.JSON(http.StatusOK, gin.H{"message": "Property created", "data": property}) } diff --git a/buildtime/server/controller/valueController.go b/buildtime/server/controller/valueController.go index e357d9002..36fbb79a0 100644 --- a/buildtime/server/controller/valueController.go +++ b/buildtime/server/controller/valueController.go @@ -244,18 +244,24 @@ func (vc *ValueController) GetValuesFromPropertyId(c *gin.Context) { } func (vc *ValueController) DeleteValueFromPropertyId(c *gin.Context) { + valueId := c.Param("valueId") propertyId := c.Param("propertyId") + valueIdInt, err := strconv.Atoi(valueId) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid value id"}) + return + } propertyIdInt, err := strconv.Atoi(propertyId) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid property id"}) return } - err = vc.valueService.DeleteValueFromPropertyId(propertyIdInt) + err = vc.valueService.DeleteValueFromPropertyId(valueIdInt, propertyIdInt) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - c.JSON(http.StatusOK, gin.H{"message": "Value deleted from Property", "propertyId": propertyIdInt}) + c.JSON(http.StatusOK, gin.H{"message": "Value deleted from Property", "valueId": valueIdInt, "propertyId": propertyIdInt}) } func (vc *ValueController) GetValue(c *gin.Context) { @@ -272,3 +278,62 @@ func (vc *ValueController) GetValue(c *gin.Context) { } c.JSON(http.StatusOK, gin.H{"message": "Value retrieved", "id": idInt, "data": value}) } + +func (vc *ValueController) CreateTerminalPropertyForProductGroupId(c *gin.Context) { + productGroupId := c.Param("productGroupId") + propertyTypeId := c.Param("propertyTypeId") + value := c.Param("value") + productGroupIdInt, err := strconv.Atoi(productGroupId) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product group id"}) + return + } + propertyTypeIdInt, err := strconv.Atoi(propertyTypeId) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid property type id"}) + return + } + err = vc.valueService.CreateTerminalPropertyForProductGroupId(productGroupIdInt, propertyTypeIdInt, value) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusOK, gin.H{"message": "Terminal Property created for ProductGroup", "productGroupId": productGroupIdInt, "propertyTypeId": propertyTypeIdInt, "value": value}) +} + +func (vc *ValueController) CreateTerminalPropertyForProductId(c *gin.Context) { + productId := c.Param("productId") + propertyTypeId := c.Param("propertyTypeId") + value := c.Param("value") + productIdInt, err := strconv.Atoi(productId) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product id"}) + return + } + propertyTypeIdInt, err := strconv.Atoi(propertyTypeId) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid property type id"}) + return + } + err = vc.valueService.CreateTerminalPropertyForProductId(productIdInt, propertyTypeIdInt, value) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusOK, gin.H{"message": "Terminal Property created for Product", "productId": productIdInt, "propertyTypeId": propertyTypeIdInt, "value": value}) +} + +func (vc *ValueController) SetTerminalValueForProperty(c *gin.Context) { + propertyId, err := strconv.Atoi(c.Param("propertyId")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid property ID"}) + return + } + value := c.Param("value") + err = vc.valueService.SetTerminalValueForProperty(propertyId, value) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusOK, gin.H{"message": "Terminal value set for property successfully"}) +} diff --git a/buildtime/server/repositories/valueRepository.go b/buildtime/server/repositories/valueRepository.go index 91be631eb..55264d626 100644 --- a/buildtime/server/repositories/valueRepository.go +++ b/buildtime/server/repositories/valueRepository.go @@ -211,6 +211,30 @@ func (vr *ValueRepository) GetValuesFromPropertyTypeId(propertyTypeId int) ([]*m return values, nil } +func (vr *ValueRepository) CreatePropertyFromPropertyTypeId(propertyTypeId int, productGroupId int, productId int) (models.Property, error) { + // Implement the logic to create a property from the given propertyTypeId + query := `INSERT INTO properties(label, description, propertytypeid) SELECT label, description, id FROM propertytypes WHERE id=$1 RETURNING id, label, description` + var property models.Property + err := vr.db.QueryRow(query, propertyTypeId).Scan(&property.ID, &property.Label, &property.Description) + if err != nil { + return models.Property{}, err + } + property.PropertyTypeID = propertyTypeId + property.ProductGroupID = productGroupId + property.ProductID = productId + err = vr.db.QueryRow(`UPDATE properties SET productgroupid=$1, productid=$2 WHERE id=$3 RETURNING id`, productGroupId, productId, property.ID).Scan(&property.ID) + if err != nil { + return models.Property{}, err + } + + err = vr.copyValuesFromPropertyTypeToProperty(propertyTypeId, property.ID) + if err != nil { + return models.Property{}, err + } + + return property, nil +} + func (vr *ValueRepository) GetValuesFromPropertyId(propertyId int) ([]*models.Value, error) { // Implement the logic to retrieve the values from the database for the given propertyId query := `SELECT id, label, description, propertyId FROM values WHERE propertyId=$1` @@ -245,10 +269,10 @@ func (vr *ValueRepository) CreateValueForPropertyId(propertyId int, value *model return value, nil } -func (vr *ValueRepository) DeleteValueFromPropertyId(id int) error { - // Implement the logic to delete the value from the database for the given id - query := `DELETE FROM values WHERE id=$1` - _, err := vr.db.Exec(query, id) +func (vr *ValueRepository) 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` + _, err := vr.db.Exec(query, valueId, propertyId) if err != nil { return err } @@ -311,7 +335,7 @@ func (vr *ValueRepository) createPropertyFromProperty(productGroupId int, produc func (vr *ValueRepository) copyValuesFromPropertyTypeToProperty(propertyTypeId int, propertyId int) error { // Implement the logic to copy values from a property type to a property - query := `INSERT INTO values (propertyId, label, description) SELECT $1, label, description FROM values WHERE propertytypeid=$2` + query := `INSERT INTO values (propertyId, label, description) SELECT $1, label, description FROM values WHERE propertyid=$2` _, err := vr.db.Exec(query, propertyId, propertyTypeId) if err != nil { return err @@ -328,3 +352,61 @@ func (vr *ValueRepository) copyValuesFromPropertyToProperty(propertyIdFrom int, } return nil } + +func (vr *ValueRepository) CreateTerminalPropertyForProductGroupId(productGroupId int, propertyTypeId int, value string) error { + // Create a new property for the given productGroupId and propertyTypeId + propertyType, err := vr.GetPropertyType(propertyTypeId) + if err != nil { + return err + } + + query := `INSERT INTO properties(label, description, propertytypeid, productgroupid, value) VALUES($1, $2, $3, $4) RETURNING id` + var property models.Property + err = vr.db.QueryRow(query, propertyType.Label, propertyType.Description, propertyTypeId, productGroupId).Scan(&property.ID) + if err != nil { + return err + } + + err = vr.db.QueryRow(`INSERT INTO values(propertyid, label, description) VALUES($1, $2, $3) RETURNING id`, property.ID, value, "").Scan(&property.ID) + if err != nil { + return err + } + return nil +} + +func (vr *ValueRepository) CreateTerminalPropertyForProductId(productId int, propertyTypeId int, value string) error { + // Create a new property for the given productGroupId and propertyTypeId + propertyType, err := vr.GetPropertyType(propertyTypeId) + if err != nil { + return err + } + + query := `INSERT INTO properties(label, description, propertytypeid, productid, value) VALUES($1, $2, $3, $4, $5) RETURNING id` + var property models.Property + err = vr.db.QueryRow(query, propertyType.Label, propertyType.Description, propertyTypeId, productId, value).Scan(&property.ID) + if err != nil { + return err + } + + err = vr.db.QueryRow(`INSERT INTO values(propertyid, label, description) VALUES($1, $2, $3) RETURNING id`, property.ID, value, "").Scan(&property.ID) + if err != nil { + return err + } + return nil + +} + +func (vr *ValueRepository) SetTerminalValueForProperty(propertyId int, value string) error { + // Implement the logic to set a terminal value for a property + // remove all values from the property + _, err := vr.db.Exec(`DELETE FROM values WHERE propertyid=$1`, propertyId) + if err != nil { + return err + } + // add the new value to the property + _, err = vr.db.Exec(`INSERT INTO values(propertyid, label, description) VALUES($1, $2, $3)`, propertyId, value, "") + if err != nil { + return err + } + return nil +} diff --git a/buildtime/server/server/httpServer.go b/buildtime/server/server/httpServer.go index 1e0b882f2..6e13e3caf 100644 --- a/buildtime/server/server/httpServer.go +++ b/buildtime/server/server/httpServer.go @@ -61,20 +61,23 @@ func InitHttpServer(config *viper.Viper, dbHandler *sql.DB) HttpServer { router.DELETE("/deleteValueFromPropertyTypeId/:propertyTypeId", valueController.DeleteValueFromPropertyTypeId) // delete Value from PropertyType by ID router.GET("/getValuesFromPropertyTypeId/:propertyTypeId", valueController.GetValuesFromPropertyTypeId) // get all Values from PropertyType by ID router.GET("/getValuesFromPropertyId/:propertyId", valueController.GetValuesFromPropertyId) // get all Values from Property by ID - router.DELETE("/deleteValueFromPropertyId/:propertyId", valueController.DeleteValueFromPropertyId) // delete Value from Property by ID - router.GET("/getValue/:id", valueController.GetValue) // get Value by id + router.DELETE("/deleteValueFromPropertyId/:valueId/:propertyId", valueController.DeleteValueFromPropertyId) // delete Value from Property by ID + router.GET("/getValue/:id", valueController.GetValue) + router.POST("/SetTerminalValueForProperty/:propertyId/:value", valueController.SetTerminalValueForProperty) // set Terminal Value for Property // Product centric routing // ProductGroup - router.POST("/createProductGroup", productGroupController.CreateProductGroup) // create ProductGroup - router.PUT("/updateProductGroup", productGroupController.UpdateProductGroup) // update ProductGroup - router.DELETE("/deleteProductGroup/:id", productGroupController.DeleteProductGroup) // delete ProductGroup - router.GET("/getProductGroup/:id", productGroupController.GetProductGroup) // get ProductGroup by id - router.GET("/getProductGroupsByParentId/:parentId", productGroupController.GetProductGroupsByParentId) // get all ProductGroups by parent ID - router.DELETE("/deleteProductFromProductGroupId/:productId", productGroupController.DeleteProductFromProductGroupId) // delete Product from ProductGroup by ID - router.POST("/getPropertiesFromProductGroupId/:productGroupId", productGroupController.GetPropertiesFromProductGroupId) // get Properties from ProductGroup by ID - router.DELETE("/deletePropertyFromProductGroupId/:propertyId/:productGroupId", productGroupController.DeletePropertyFromProductGroupId) // delete Property from ProductGroup by ID - router.POST("/createPropertyToProductGroupId/:propertyTypeId/:productGroupId", productGroupController.CreatePropertyToProductGroupId) // add Property to ProductGroup by ID + router.POST("/createProductGroup", productGroupController.CreateProductGroup) // create ProductGroup + router.PUT("/updateProductGroup", productGroupController.UpdateProductGroup) // update ProductGroup + router.DELETE("/deleteProductGroup/:id", productGroupController.DeleteProductGroup) // delete ProductGroup + router.GET("/getProductGroup/:id", productGroupController.GetProductGroup) // get ProductGroup by id + router.GET("/getProductGroupsByParentId/:parentId", productGroupController.GetProductGroupsByParentId) // get all ProductGroups by parent ID + router.DELETE("/deleteProductFromProductGroupId/:productId", productGroupController.DeleteProductFromProductGroupId) // delete Product from ProductGroup by ID + router.POST("/getPropertiesFromProductGroupId/:productGroupId", productGroupController.GetPropertiesFromProductGroupId) // get Properties from ProductGroup by ID + router.DELETE("/deletePropertyFromProductGroupId/:propertyId/:productGroupId", productGroupController.DeletePropertyFromProductGroupId) // delete Property from ProductGroup by ID + router.GET("/createPropertyToProductGroupId/:propertyTypeId/:productGroupId", productGroupController.CreatePropertyToProductGroupId) // add Property to ProductGroup by ID + router.POST("/createTerminalPropertyForProductGroupId/:productGroupId/:propertyTypeId/:value", valueController.CreateTerminalPropertyForProductGroupId) // create Terminal Property for ProductGroup by ID + router.POST("/createTerminalPropertyForProductId/:productId/:propertyTypeId/:value", valueController.CreateTerminalPropertyForProductId) // create Terminal Property for Product by ID // Product router.POST("/createProduct", productController.CreateProduct) // create Product diff --git a/buildtime/server/services/valueService.go b/buildtime/server/services/valueService.go index ee63b6781..dd866da80 100644 --- a/buildtime/server/services/valueService.go +++ b/buildtime/server/services/valueService.go @@ -71,12 +71,16 @@ func (vs *ValueService) GetValuesFromPropertyTypeId(propertyTypeId int) ([]*mode return vs.valueRepository.GetValuesFromPropertyTypeId(propertyTypeId) } +func (vs *ValueService) CreatePropertyFromPropertyTypeId(propertyTypeId int, productGroupId int, productId int) (models.Property, error) { + return vs.valueRepository.CreatePropertyFromPropertyTypeId(propertyTypeId, productGroupId, productId) +} + func (vs *ValueService) GetValuesFromPropertyId(propertyId int) ([]*models.Value, error) { return vs.valueRepository.GetValuesFromPropertyId(propertyId) } -func (vs *ValueService) DeleteValueFromPropertyId(id int) error { - return vs.valueRepository.DeleteValueFromPropertyId(id) +func (vs *ValueService) DeleteValueFromPropertyId(valueId int, propertyId int) error { + return vs.valueRepository.DeleteValueFromPropertyId(valueId, propertyId) } func (vs *ValueService) CreateValueForPropertyId(propertyId int, value *models.Value) (*models.Value, error) { @@ -86,3 +90,15 @@ func (vs *ValueService) CreateValueForPropertyId(propertyId int, value *models.V func (vs *ValueService) GetValue(id int) (*models.Value, error) { return vs.valueRepository.GetValue(id) } + +func (vs *ValueService) CreateTerminalPropertyForProductGroupId(productGroupId int, propertyTypeId int, value string) error { + return vs.valueRepository.CreateTerminalPropertyForProductGroupId(productGroupId, propertyTypeId, value) +} + +func (vs *ValueService) CreateTerminalPropertyForProductId(productId int, propertyTypeId int, value string) error { + return vs.valueRepository.CreateTerminalPropertyForProductId(productId, propertyTypeId, value) +} + +func (vs *ValueService) SetTerminalValueForProperty(propertyId int, value string) error { + return vs.valueRepository.SetTerminalValueForProperty(propertyId, value) +}