Produkte und Properties im Server

This commit is contained in:
2026-08-16 18:22:05 +02:00
parent 5b60189b07
commit 5060fe5a2e
10 changed files with 818 additions and 14 deletions
+46 -6
View File
@@ -72,7 +72,7 @@ CREATE TABLE tabelle_a (
- updateValueFromValueId
- add
- addValueToPropertyType
- Produkte haben zusätzlich zur ID, Label und Beschreibung noch eine externalId.
@@ -107,7 +107,7 @@ CREATE TABLE IF NOT EXISTS values (
id BIGINT PRIMARY KEY DEFAULT nextval('global_id_seq'),
Label TEXT,
description TEXT,
propertyId BIGINT
propertyGroupId BIGINT
);
-- Property Table
@@ -163,11 +163,8 @@ CREATE TABLE IF NOT EXISTS media (
mediaType TEXT,
externalId BIGINT
);
```
## Open Aufsetzen des Source Codes:
````
@@ -218,4 +215,47 @@ go get github.com/gin-contrib/cors
## Server API
Die Server-API baut auf HTTP und auf REST auf. Antworten werden im JSON Format gesendet,ebenso, wie neu anzulegende Daten oder zu aktualisierende Daten.
Die Server-API baut auf HTTP und auf REST auf. Antworten werden im JSON Format gesendet,ebenso, wie neu anzulegende Daten oder zu aktualisierende Daten.
Generell werden Daten im JSON Format ausgetauscht. Z.B. wird ein *Value* Objekt in From von *application/json Daten* übergeben:
```gettext
put: http://server:port/updatePropertyType
```
benötigt folgende Struktur im Anfragekörper:
```json
{
"id": 1000003,
"label": "Colour",
"description": "System wide colors",
"propertyTypeGroupId": 100002
}
```
und liefert als Ergebnis (wenn kein Fehler auftritt):
```json
{
"data": {
"id": 1000003,
"label": "Colour",
"description": "System wide colors",
"propertyTypeGroupId": 100002
},
"message": "PropertyType updated"
}
```
Wenn Daten zurückkommen, so wie hier im Beispiel, dann werden sie im *"data"* Tag geschrieben. Meistens kommt auch noch eine Nachricht mit, die in *"message"* steht.
Im Falle eines Fehler kommt eine entsprechende Nachricht zurück (z.B. wenn es keinen PropertyType mit der entsprechenden *ID* gibt):
```json
{
"error": "sql: no rows in result set"
}
```
### Value und Property Funktionen
@@ -0,0 +1,142 @@
package controller
import (
"net/http"
"simplycpq/models"
"simplycpq/services"
"strconv"
"github.com/gin-gonic/gin"
)
type ProductController struct {
productService *services.ProductService
productGroupService *services.ProductGroupService
valueService *services.ValueService
}
func NewProductController(productService *services.ProductService, productGroupService *services.ProductGroupService, valueService *services.ValueService) *ProductController {
return &ProductController{
productService: productService,
productGroupService: productGroupService,
valueService: valueService,
}
}
func (pc *ProductController) CreateProduct(c *gin.Context) {
var product models.Product
if err := c.ShouldBindJSON(&product); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
createdProduct, err := pc.productService.CreateProduct(&product)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "product created successfully", "data": createdProduct})
}
func (pc *ProductController) UpdateProduct(c *gin.Context) {
var product models.Product
if err := c.ShouldBindJSON(&product); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := pc.productService.UpdateProduct(&product); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "product updated successfully"})
}
func (pc *ProductController) DeleteProduct(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product id"})
return
}
if err := pc.productService.DeleteProduct(id); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "product deleted successfully"})
}
func (pc *ProductController) GetProduct(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product id"})
return
}
product, err := pc.productService.GetProductById(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "product retrieved successfully", "product": product})
}
func (pc *ProductController) GetProductsByGroupId(c *gin.Context) {
groupId, err := strconv.Atoi(c.Param("groupId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid group id"})
return
}
products, err := pc.productService.GetProductsByGroupId(groupId)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "products retrieved successfully", "groupId": groupId, "products": products})
}
func (pc *ProductController) AddPropertyToProductId(c *gin.Context) {
productId, err := strconv.Atoi(c.Param("productId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product id"})
return
}
propertyId, err := strconv.Atoi(c.Param("propertyId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid property id"})
return
}
if err := pc.productService.AddPropertyToProduct(productId, propertyId); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "property added to product successfully", "productId": productId, "propertyId": propertyId})
}
func (pc *ProductController) DeletePropertyFromProductId(c *gin.Context) {
productId, err := strconv.Atoi(c.Param("productId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product id"})
return
}
propertyId, err := strconv.Atoi(c.Param("propertyId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid property id"})
return
}
if err := pc.productService.DeletePropertyFromProduct(productId, propertyId); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "property deleted from product successfully", "productId": productId, "propertyId": propertyId})
}
func (pc *ProductController) GetPropertiesFromProductId(c *gin.Context) {
productId, err := strconv.Atoi(c.Param("productId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product id"})
return
}
properties, err := pc.productService.GetPropertiesFromProduct(productId)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "properties retrieved from product successfully", "productId": productId, "properties": properties})
}
@@ -0,0 +1,162 @@
package controller
import (
"net/http"
"simplycpq/models"
"simplycpq/services"
"strconv"
"github.com/gin-gonic/gin"
)
type ProductGroupController struct {
productGroupService *services.ProductGroupService
valueService *services.ValueService
}
func NewProductGroupController(productGroupService *services.ProductGroupService, valueService *services.ValueService) *ProductGroupController {
return &ProductGroupController{
productGroupService: productGroupService,
valueService: valueService,
}
}
func (pgc *ProductGroupController) CreateProductGroup(c *gin.Context) {
var productGroup models.ProductGroup
if err := c.ShouldBindJSON(&productGroup); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
createdProductGroup, err := pgc.productGroupService.CreateProductGroup(&productGroup)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, createdProductGroup)
}
func (pgc *ProductGroupController) UpdateProductGroup(c *gin.Context) {
var productGroup models.ProductGroup
if err := c.ShouldBindJSON(&productGroup); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
updatedProductGroup, err := pgc.productGroupService.UpdateProductGroup(&productGroup)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, updatedProductGroup)
}
func (pgc *ProductGroupController) DeleteProductGroup(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
return
}
err = pgc.productGroupService.DeleteProductGroup(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "ProductGroup deleted successfully"})
}
func (pgc *ProductGroupController) GetProductGroup(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
return
}
productGroup, err := pgc.productGroupService.GetProductGroup(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, productGroup)
}
func (pgc *ProductGroupController) GetProductGroupsByParentId(c *gin.Context) {
parentId, err := strconv.Atoi(c.Param("parentId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid parent ID"})
return
}
productGroups, err := pgc.productGroupService.GetProductGroupsByParentId(parentId)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, productGroups)
}
func (pgc *ProductGroupController) DeleteProductFromProductGroupId(c *gin.Context) {
productId, err := strconv.Atoi(c.Param("productId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid product ID"})
return
}
err = pgc.productGroupService.DeleteProductFromProductGroupId(productId)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Product deleted from product group successfully"})
}
func (pgc *ProductGroupController) GetPropertiesFromProductGroupId(c *gin.Context) {
productGroupId, err := strconv.Atoi(c.Param("productGroupId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid product group ID"})
return
}
properties, err := pgc.productGroupService.GetPropertiesFromProductGroupId(productGroupId)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, properties)
}
func (pgc *ProductGroupController) DeletePropertyFromProductGroupId(c *gin.Context) {
propertyId, err := strconv.Atoi(c.Param("propertyId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid property ID"})
return
}
productGroupId, err := strconv.Atoi(c.Param("productGroupId"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid product group ID"})
return
}
err = pgc.productGroupService.DeletePropertyFromProductGroup(productGroupId, propertyId)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Property deleted from product group successfully"})
}
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)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, property2)
}
+2
View File
@@ -19,6 +19,8 @@ type Property struct {
Label string `json:"label"`
Description string `json:"description"`
PropertyTypeID int `json:"propertyTypeId"`
ProductID int `json:"productId"`
ProductGroupID int `json:"productGroupId"`
}
type Value struct {
@@ -0,0 +1,152 @@
package repositories
import (
"database/sql"
"simplycpq/models"
)
type ProductGroupRepository struct {
db *sql.DB
valueRepository *ValueRepository
}
func NewProductGroupRepository(db *sql.DB, valueRepository *ValueRepository) *ProductGroupRepository {
return &ProductGroupRepository{
db: db,
valueRepository: valueRepository,
}
}
func (r *ProductGroupRepository) CreateProductGroup(productGroup *models.ProductGroup) (*models.ProductGroup, error) {
// Insert the product group into the database
query := "INSERT INTO product_groups (label, description, parentgroupid) VALUES($1,$2,$3) RETURNING id"
err := r.db.QueryRow(query, productGroup.Label, productGroup.Description, productGroup.ParentGroupID).Scan(&productGroup.ID)
if err != nil {
return nil, err
}
// get all properties from parent group and copy them to the new group
if productGroup.ParentGroupID != 0 {
properties, err := r.GetPropertiesFromProductGroupId(productGroup.ParentGroupID)
if err != nil {
return nil, err
}
for _, prop := range properties {
_, err := r.valueRepository.createPropertyFromProperty(productGroup.ID, 0, prop)
if err != nil {
return nil, err
}
}
}
return productGroup, nil
}
func (r *ProductGroupRepository) UpdateProductGroup(productGroup *models.ProductGroup) (*models.ProductGroup, error) {
query := "UPDATE product_groups SET label=$1, description=$2, parentgroupid=$3 WHERE id=$4"
_, err := r.db.Exec(query, productGroup.Label, productGroup.Description, productGroup.ParentGroupID, productGroup.ID)
if err != nil {
return nil, err
}
return productGroup, nil
}
func (r *ProductGroupRepository) DeleteProductGroup(id int) error {
query := "DELETE FROM product_groups WHERE id=$1"
_, err := r.db.Exec(query, id)
if err != nil {
return err
}
return nil
}
func (r *ProductGroupRepository) GetProductGroup(id int) (*models.ProductGroup, error) {
query := "SELECT id, label, description, parentgroupid FROM product_groups WHERE id=$1"
row := r.db.QueryRow(query, id)
productGroup := &models.ProductGroup{}
err := row.Scan(&productGroup.ID, &productGroup.Label, &productGroup.Description, &productGroup.ParentGroupID)
if err != nil {
return nil, err
}
return productGroup, nil
}
func (r *ProductGroupRepository) GetProductGroupsByParentId(parentId int) ([]*models.ProductGroup, error) {
query := "SELECT id, label, description, parentgroupid FROM product_groups WHERE parentgroupid=$1"
rows, err := r.db.Query(query, parentId)
if err != nil {
return nil, err
}
defer rows.Close()
var productGroups []*models.ProductGroup
for rows.Next() {
var productGroup models.ProductGroup
err := rows.Scan(&productGroup.ID, &productGroup.Label, &productGroup.Description, &productGroup.ParentGroupID)
if err != nil {
return nil, err
}
productGroups = append(productGroups, &productGroup)
}
if err = rows.Err(); err != nil {
return nil, err
}
return productGroups, nil
}
func (r *ProductGroupRepository) DeleteProductFromProductGroupId(productGroupId int) error {
query := "DELETE FROM products WHERE productgroupid=$1"
_, err := r.db.Exec(query, productGroupId)
if err != nil {
return err
}
return nil
}
func (r *ProductGroupRepository) GetPropertiesFromProductGroupId(productGroupId int) ([]*models.Property, error) {
query := "SELECT id, label, description, propertytypeid, productid, productgroupid FROM properties WHERE productgroupid=$1"
rows, err := r.db.Query(query, productGroupId)
if err != nil {
return nil, err
}
defer rows.Close()
var properties []*models.Property
for rows.Next() {
var property models.Property
err := rows.Scan(&property.ID, &property.Label, &property.Description, &property.PropertyTypeID, &property.ProductID, &property.ProductGroupID)
if err != nil {
return nil, err
}
properties = append(properties, &property)
}
if err = rows.Err(); err != nil {
return nil, err
}
return properties, nil
}
func (r *ProductGroupRepository) DeletePropertyFromProductGroup(productGroupId int, propertyId int) error {
query := "DELETE FROM properties WHERE productgroupid=$1 AND id=$2"
_, err := r.db.Exec(query, productGroupId, propertyId)
if err != nil {
return err
}
return nil
}
func (r *ProductGroupRepository) CreatePropertyFromProductGroup(productGroupId int, property *models.Property) (*models.Property, error) {
query := "INSERT INTO properties (label, description, propertytypeid, productid, productgroupid) VALUES($1,$2,$3,$4,$5) RETURNING id"
err := r.db.QueryRow(query, property.Label, property.Description, property.PropertyTypeID, property.ProductID, productGroupId).Scan(&property.ID)
if err != nil {
return nil, err
}
// copy property values from parent group to new property
if productGroupId != 0 {
err := r.valueRepository.copyValuesFromPropertyTypeToProperty(property.ID, property.PropertyTypeID)
if err != nil {
return nil, err
}
}
return property, nil
}
@@ -0,0 +1,126 @@
package repositories
import (
"database/sql"
"simplycpq/models"
)
type ProductRepository struct {
dbHandler *sql.DB
productGroupRepository *ProductGroupRepository
valueRepository *ValueRepository
}
func NewProductRepository(dbHandler *sql.DB, productGroupRepository *ProductGroupRepository, valueRepository *ValueRepository) *ProductRepository {
return &ProductRepository{
dbHandler: dbHandler,
productGroupRepository: productGroupRepository,
valueRepository: valueRepository,
}
}
func (pr *ProductRepository) CreateProduct(product *models.Product) (*models.Product, error) {
// Implement the logic to insert a new product into the database
query := "INSERT INTO products (label, externalId, description, productGroupId) VALUES ($1, $2, $3, $4) RETURNING id"
err := pr.dbHandler.QueryRow(query, product.Label, product.ExternalID, product.Description, product.ProductGroupID).Scan(&product.ID)
if err != nil {
return nil, err
}
// copy Properties from ProductGroup to Product
properties, err := pr.productGroupRepository.GetPropertiesFromProductGroupId(product.ProductGroupID)
if err != nil {
return nil, err
}
for _, property := range properties {
_, err := pr.valueRepository.createPropertyFromProperty(0, product.ID, property)
if err != nil {
return nil, err
}
}
return product, nil
}
func (pr *ProductRepository) GetProductById(id int) (*models.Product, error) {
// Implement the logic to retrieve a product by its ID from the database
query := "SELECT id, label, externalId, description, productGroupId FROM products WHERE id = $1"
row := pr.dbHandler.QueryRow(query, id)
product := &models.Product{}
err := row.Scan(&product.ID, &product.Label, &product.ExternalID, &product.Description, &product.ProductGroupID)
if err != nil {
return nil, err
}
return product, nil
}
func (pr *ProductRepository) UpdateProduct(product *models.Product) error {
// Implement the logic to update an existing product in the database
query := "UPDATE products SET label = $1, externalId = $2, description = $3, productGroupId = $4 WHERE id = $5"
_, err := pr.dbHandler.Exec(query, product.Label, product.ExternalID, product.Description, product.ProductGroupID, product.ID)
return err
}
func (pr *ProductRepository) DeleteProduct(id int) error {
// Implement the logic to delete a product from the database
query := "DELETE FROM products WHERE id = $1"
_, err := pr.dbHandler.Exec(query, id)
return err
}
func (pr *ProductRepository) GetProductsByGroupId(groupId int) ([]*models.Product, error) {
// Implement the logic to retrieve all products by their group ID from the database
query := "SELECT id, label, externalId, description, productGroupId FROM products WHERE productGroupId = $1"
rows, err := pr.dbHandler.Query(query, groupId)
if err != nil {
return nil, err
}
defer rows.Close()
products := []*models.Product{}
for rows.Next() {
product := &models.Product{}
err := rows.Scan(&product.ID, &product.Label, &product.ExternalID, &product.Description, &product.ProductGroupID)
if err != nil {
return nil, err
}
products = append(products, product)
}
return products, nil
}
func (pr *ProductRepository) AddPropertyToProduct(productId int, propertyId int) error {
// Implement the logic to add a property to a product in the database
query := "INSERT INTO product_properties (productId, propertyId) VALUES ($1, $2)"
_, err := pr.dbHandler.Exec(query, productId, propertyId)
return err
}
func (pr *ProductRepository) DeletePropertyFromProduct(productId int, propertyId int) error {
// Implement the logic to delete a property from a product in the database
query := "DELETE FROM product_properties WHERE productId = $1 AND propertyId = $2"
_, err := pr.dbHandler.Exec(query, productId, propertyId)
return err
}
func (pr *ProductRepository) GetPropertiesFromProduct(productId int) ([]*models.Property, error) {
// Implement the logic to retrieve all properties from a product in the database
query := "SELECT id, label, description, propertyTypeId, productId, productGroupId FROM properties WHERE productId = $1"
rows, err := pr.dbHandler.Query(query, productId)
if err != nil {
return nil, err
}
defer rows.Close()
properties := []*models.Property{}
for rows.Next() {
property := &models.Property{}
err := rows.Scan(&property.ID, &property.Label, &property.Description, &property.PropertyTypeID, &property.ProductID, &property.ProductGroupID)
if err != nil {
return nil, err
}
properties = append(properties, property)
}
return properties, nil
}
@@ -267,6 +267,48 @@ func (vr *ValueRepository) GetValue(id int) (*models.Value, error) {
return &value, nil
}
func (vr *ValueRepository) createPropertyFromPropertyType(productGroupId int, productId int, propertyType *models.PropertyType) (*models.Property, error) {
query := `INSERT INTO properties (label, description, propertytypeid, productid, productgroupid) VALUES ($1, $2, $3, $4, $5) RETURNING id`
var property models.Property
err := vr.db.QueryRow(query, propertyType.Label, propertyType.Description, propertyType.ID, productId, productGroupId).Scan(&property.ID)
if err != nil {
return nil, err
}
property.Label = propertyType.Label
property.Description = propertyType.Description
property.PropertyTypeID = propertyType.ID
property.ProductID = productId
property.ProductGroupID = productGroupId
// Copy values from property type to property
err = vr.copyValuesFromPropertyTypeToProperty(propertyType.ID, property.ID)
if err != nil {
return nil, err
}
return &property, nil
}
func (vr *ValueRepository) createPropertyFromProperty(productGroupId int, productId int, property *models.Property) (*models.Property, error) {
query := `INSERT INTO properties (label, description, propertytypeid, productid, productgroupid) VALUES ($1, $2, $3, $4, $5) RETURNING id`
var newProperty models.Property
err := vr.db.QueryRow(query, property.Label, property.Description, property.PropertyTypeID, productId, productGroupId).Scan(&newProperty.ID)
if err != nil {
return nil, err
}
newProperty.Label = property.Label
newProperty.Description = property.Description
newProperty.PropertyTypeID = property.PropertyTypeID
newProperty.ProductID = productId
newProperty.ProductGroupID = productGroupId
// Copy values from property type to property
err = vr.copyValuesFromPropertyToProperty(property.ID, newProperty.ID)
if err != nil {
return nil, err
}
return &newProperty, nil
}
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`
+39 -8
View File
@@ -15,20 +15,30 @@ import (
)
type HttpServer struct {
config *viper.Viper
router *gin.Engine
dbHandler *sql.DB
valueController *controller.ValueController
config *viper.Viper
router *gin.Engine
dbHandler *sql.DB
valueController *controller.ValueController
productGroupController *controller.ProductGroupController
productController *controller.ProductController
}
func InitHttpServer(config *viper.Viper, dbHandler *sql.DB) HttpServer {
// repository initialisation:
valueRepository := repositories.NewValueRepository(dbHandler)
productGroupRepository := repositories.NewProductGroupRepository(dbHandler, valueRepository)
productRepository := repositories.NewProductRepository(dbHandler, productGroupRepository, valueRepository)
// service initialisation:
valueService := services.NewValueService(valueRepository)
productGroupService := services.NewProductGroupService(productGroupRepository)
productService := services.NewProductService(productRepository)
// controller initialisation:
valueController := controller.NewValueController(valueService)
productGroupController := controller.NewProductGroupController(productGroupService, valueService)
productController := controller.NewProductController(productService, productGroupService, valueService)
// Service API
router := gin.Default()
@@ -55,13 +65,34 @@ func InitHttpServer(config *viper.Viper, dbHandler *sql.DB) HttpServer {
router.GET("/getValue/:id", valueController.GetValue) // get Value by id
// 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
// Product
router.POST("/createProduct", productController.CreateProduct) // create Product
router.PUT("/updateProduct", productController.UpdateProduct) // update Product
router.DELETE("/deleteProduct/:id", productController.DeleteProduct) // delete Product
router.GET("/getProduct/:id", productController.GetProduct) // get Product by id
router.GET("/getProductsByGroupId/:groupId", productController.GetProductsByGroupId) // get all Products by group ID
router.POST("/addPropertyToProductId/:productId", productController.AddPropertyToProductId) // add Property to Product by ID
router.DELETE("/deletePropertyFromProductId/:productId", productController.DeletePropertyFromProductId) // delete Property from Product by ID
// server
return HttpServer{
config: config,
router: router,
dbHandler: dbHandler,
valueController: valueController,
config: config,
router: router,
dbHandler: dbHandler,
valueController: valueController,
productGroupController: productGroupController,
productController: productController,
}
}
@@ -0,0 +1,56 @@
package services
import (
"simplycpq/models"
"simplycpq/repositories"
)
type ProductGroupService struct {
productGroupRepository *repositories.ProductGroupRepository
}
func NewProductGroupService(productGroupRepository *repositories.ProductGroupRepository) *ProductGroupService {
return &ProductGroupService{
productGroupRepository: productGroupRepository,
}
}
func (s *ProductGroupService) CreateProductGroup(productGroup *models.ProductGroup) (*models.ProductGroup, error) {
return s.productGroupRepository.CreateProductGroup(productGroup)
}
func (s *ProductGroupService) UpdateProductGroup(productGroup *models.ProductGroup) (*models.ProductGroup, error) {
return s.productGroupRepository.UpdateProductGroup(productGroup)
}
func (s *ProductGroupService) DeleteProductGroup(id int) error {
return s.productGroupRepository.DeleteProductGroup(id)
}
func (s *ProductGroupService) GetProductGroup(id int) (*models.ProductGroup, error) {
return s.productGroupRepository.GetProductGroup(id)
}
func (s *ProductGroupService) GetPropertiesFromProductGroupId(id int) ([]*models.Property, error) {
return s.productGroupRepository.GetPropertiesFromProductGroupId(id)
}
func (s *ProductGroupService) GetProductGroupsByParentId(parentId int) ([]*models.ProductGroup, error) {
return s.productGroupRepository.GetProductGroupsByParentId(parentId)
}
func (s *ProductGroupService) DeleteProductFromProductGroupId(productGroupId int) error {
return s.productGroupRepository.DeleteProductFromProductGroupId(productGroupId)
}
func (s *ProductGroupService) GetPropertiesFromProductGroup(productGroupId int) ([]*models.Property, error) {
return s.productGroupRepository.GetPropertiesFromProductGroupId(productGroupId)
}
func (s *ProductGroupService) DeletePropertyFromProductGroup(productGroupId int, propertyId int) error {
return s.productGroupRepository.DeletePropertyFromProductGroup(productGroupId, propertyId)
}
func (s *ProductGroupService) CreatePropertyToProductGroupId(productGroupId int, property *models.Property) (*models.Property, error) {
return s.productGroupRepository.CreatePropertyFromProductGroup(productGroupId, property)
}
@@ -0,0 +1,51 @@
package services
import (
"simplycpq/models"
"simplycpq/repositories"
)
type ProductService struct {
productRepository *repositories.ProductRepository
}
func NewProductService(productRepository *repositories.ProductRepository) *ProductService {
return &ProductService{
productRepository: productRepository,
}
}
func (s *ProductService) CreateProduct(product *models.Product) (*models.Product, error) {
return s.productRepository.CreateProduct(product)
}
func (s *ProductService) UpdateProduct(product *models.Product) error {
return s.productRepository.UpdateProduct(product)
}
func (s *ProductService) DeleteProduct(id int) error {
return s.productRepository.DeleteProduct(id)
}
func (s *ProductService) GetProduct(id int) (*models.Product, error) {
return s.productRepository.GetProductById(id)
}
func (s *ProductService) GetProductById(id int) (*models.Product, error) {
return s.productRepository.GetProductById(id)
}
func (s *ProductService) GetProductsByGroupId(groupId int) ([]*models.Product, error) {
return s.productRepository.GetProductsByGroupId(groupId)
}
func (s *ProductService) AddPropertyToProduct(productId int, propertyId int) error {
return s.productRepository.AddPropertyToProduct(productId, propertyId)
}
func (s *ProductService) DeletePropertyFromProduct(productId int, propertyId int) error {
return s.productRepository.DeletePropertyFromProduct(productId, propertyId)
}
func (s *ProductService) GetPropertiesFromProduct(productId int) ([]*models.Property, error) {
return s.productRepository.GetPropertiesFromProduct(productId)
}