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 }