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 productgroups (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 productgroups 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 productgroups 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 productgroups 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 productgroups 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 }