310 lines
9.0 KiB
Go
310 lines
9.0 KiB
Go
|
|
package repository
|
||
|
|
|
||
|
|
import (
|
||
|
|
"apskel-pos-be/internal/entities"
|
||
|
|
"context"
|
||
|
|
"database/sql"
|
||
|
|
|
||
|
|
"github.com/google/uuid"
|
||
|
|
)
|
||
|
|
|
||
|
|
type ProductIngredientRepository struct {
|
||
|
|
db *sql.DB
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewProductIngredientRepository(db *sql.DB) *ProductIngredientRepository {
|
||
|
|
return &ProductIngredientRepository{db: db}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *ProductIngredientRepository) Create(ctx context.Context, productIngredient *entities.ProductIngredient) error {
|
||
|
|
query := `
|
||
|
|
INSERT INTO product_ingredients (id, organization_id, outlet_id, product_id, ingredient_id, quantity, created_at, updated_at)
|
||
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||
|
|
`
|
||
|
|
|
||
|
|
_, err := r.db.ExecContext(ctx, query,
|
||
|
|
productIngredient.ID,
|
||
|
|
productIngredient.OrganizationID,
|
||
|
|
productIngredient.OutletID,
|
||
|
|
productIngredient.ProductID,
|
||
|
|
productIngredient.IngredientID,
|
||
|
|
productIngredient.Quantity,
|
||
|
|
productIngredient.CreatedAt,
|
||
|
|
productIngredient.UpdatedAt,
|
||
|
|
)
|
||
|
|
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *ProductIngredientRepository) GetByID(ctx context.Context, id, organizationID uuid.UUID) (*entities.ProductIngredient, error) {
|
||
|
|
query := `
|
||
|
|
SELECT pi.id, pi.organization_id, pi.outlet_id, pi.product_id, pi.ingredient_id, pi.quantity, pi.created_at, pi.updated_at,
|
||
|
|
p.id, p.organization_id, p.category_id, p.sku, p.name, p.description, p.price, p.cost, p.business_type, p.image_url, p.printer_type, p.unit_id, p.has_ingredients, p.metadata, p.is_active, p.created_at, p.updated_at,
|
||
|
|
i.id, i.organization_id, i.outlet_id, i.name, i.unit_id, i.cost, i.stock, i.is_semi_finished, i.is_active, i.metadata, i.created_at, i.updated_at
|
||
|
|
FROM product_ingredients pi
|
||
|
|
LEFT JOIN products p ON pi.product_id = p.id
|
||
|
|
LEFT JOIN ingredients i ON pi.ingredient_id = i.id
|
||
|
|
WHERE pi.id = $1 AND pi.organization_id = $2
|
||
|
|
`
|
||
|
|
|
||
|
|
productIngredient := &entities.ProductIngredient{}
|
||
|
|
product := &entities.Product{}
|
||
|
|
ingredient := &entities.Ingredient{}
|
||
|
|
|
||
|
|
err := r.db.QueryRowContext(ctx, query, id, organizationID).Scan(
|
||
|
|
&productIngredient.ID,
|
||
|
|
&productIngredient.OrganizationID,
|
||
|
|
&productIngredient.OutletID,
|
||
|
|
&productIngredient.ProductID,
|
||
|
|
&productIngredient.IngredientID,
|
||
|
|
&productIngredient.Quantity,
|
||
|
|
&productIngredient.CreatedAt,
|
||
|
|
&productIngredient.UpdatedAt,
|
||
|
|
&product.ID,
|
||
|
|
&product.OrganizationID,
|
||
|
|
&product.CategoryID,
|
||
|
|
&product.SKU,
|
||
|
|
&product.Name,
|
||
|
|
&product.Description,
|
||
|
|
&product.Price,
|
||
|
|
&product.Cost,
|
||
|
|
&product.BusinessType,
|
||
|
|
&product.ImageURL,
|
||
|
|
&product.PrinterType,
|
||
|
|
&product.UnitID,
|
||
|
|
&product.HasIngredients,
|
||
|
|
&product.Metadata,
|
||
|
|
&product.IsActive,
|
||
|
|
&product.CreatedAt,
|
||
|
|
&product.UpdatedAt,
|
||
|
|
&ingredient.ID,
|
||
|
|
&ingredient.OrganizationID,
|
||
|
|
&ingredient.OutletID,
|
||
|
|
&ingredient.Name,
|
||
|
|
&ingredient.UnitID,
|
||
|
|
&ingredient.Cost,
|
||
|
|
&ingredient.Stock,
|
||
|
|
&ingredient.IsSemiFinished,
|
||
|
|
&ingredient.IsActive,
|
||
|
|
&ingredient.Metadata,
|
||
|
|
&ingredient.CreatedAt,
|
||
|
|
&ingredient.UpdatedAt,
|
||
|
|
)
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
productIngredient.Product = product
|
||
|
|
productIngredient.Ingredient = ingredient
|
||
|
|
return productIngredient, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *ProductIngredientRepository) GetByProductID(ctx context.Context, productID, organizationID uuid.UUID) ([]*entities.ProductIngredient, error) {
|
||
|
|
query := `
|
||
|
|
SELECT pi.id, pi.organization_id, pi.outlet_id, pi.product_id, pi.ingredient_id, pi.quantity, pi.created_at, pi.updated_at,
|
||
|
|
p.id, p.organization_id, p.category_id, p.sku, p.name, p.description, p.price, p.cost, p.business_type, p.image_url, p.printer_type, p.unit_id, p.has_ingredients, p.metadata, p.is_active, p.created_at, p.updated_at,
|
||
|
|
i.id, i.organization_id, i.outlet_id, i.name, i.unit_id, i.cost, i.stock, i.is_semi_finished, i.is_active, i.metadata, i.created_at, i.updated_at
|
||
|
|
FROM product_ingredients pi
|
||
|
|
LEFT JOIN products p ON pi.product_id = p.id
|
||
|
|
LEFT JOIN ingredients i ON pi.ingredient_id = i.id
|
||
|
|
WHERE pi.product_id = $1 AND pi.organization_id = $2
|
||
|
|
ORDER BY pi.created_at DESC
|
||
|
|
`
|
||
|
|
|
||
|
|
rows, err := r.db.QueryContext(ctx, query, productID, organizationID)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer rows.Close()
|
||
|
|
|
||
|
|
var productIngredients []*entities.ProductIngredient
|
||
|
|
for rows.Next() {
|
||
|
|
productIngredient := &entities.ProductIngredient{}
|
||
|
|
product := &entities.Product{}
|
||
|
|
ingredient := &entities.Ingredient{}
|
||
|
|
|
||
|
|
err := rows.Scan(
|
||
|
|
&productIngredient.ID,
|
||
|
|
&productIngredient.OrganizationID,
|
||
|
|
&productIngredient.OutletID,
|
||
|
|
&productIngredient.ProductID,
|
||
|
|
&productIngredient.IngredientID,
|
||
|
|
&productIngredient.Quantity,
|
||
|
|
&productIngredient.CreatedAt,
|
||
|
|
&productIngredient.UpdatedAt,
|
||
|
|
&product.ID,
|
||
|
|
&product.OrganizationID,
|
||
|
|
&product.CategoryID,
|
||
|
|
&product.SKU,
|
||
|
|
&product.Name,
|
||
|
|
&product.Description,
|
||
|
|
&product.Price,
|
||
|
|
&product.Cost,
|
||
|
|
&product.BusinessType,
|
||
|
|
&product.ImageURL,
|
||
|
|
&product.PrinterType,
|
||
|
|
&product.UnitID,
|
||
|
|
&product.HasIngredients,
|
||
|
|
&product.Metadata,
|
||
|
|
&product.IsActive,
|
||
|
|
&product.CreatedAt,
|
||
|
|
&product.UpdatedAt,
|
||
|
|
&ingredient.ID,
|
||
|
|
&ingredient.OrganizationID,
|
||
|
|
&ingredient.OutletID,
|
||
|
|
&ingredient.Name,
|
||
|
|
&ingredient.UnitID,
|
||
|
|
&ingredient.Cost,
|
||
|
|
&ingredient.Stock,
|
||
|
|
&ingredient.IsSemiFinished,
|
||
|
|
&ingredient.IsActive,
|
||
|
|
&ingredient.Metadata,
|
||
|
|
&ingredient.CreatedAt,
|
||
|
|
&ingredient.UpdatedAt,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
productIngredient.Product = product
|
||
|
|
productIngredient.Ingredient = ingredient
|
||
|
|
productIngredients = append(productIngredients, productIngredient)
|
||
|
|
}
|
||
|
|
|
||
|
|
return productIngredients, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *ProductIngredientRepository) GetByIngredientID(ctx context.Context, ingredientID, organizationID uuid.UUID) ([]*entities.ProductIngredient, error) {
|
||
|
|
query := `
|
||
|
|
SELECT pi.id, pi.organization_id, pi.outlet_id, pi.product_id, pi.ingredient_id, pi.quantity, pi.created_at, pi.updated_at,
|
||
|
|
p.id, p.organization_id, p.category_id, p.sku, p.name, p.description, p.price, p.cost, p.business_type, p.image_url, p.printer_type, p.unit_id, p.has_ingredients, p.metadata, p.is_active, p.created_at, p.updated_at,
|
||
|
|
i.id, i.organization_id, i.outlet_id, i.name, i.unit_id, i.cost, i.stock, i.is_semi_finished, i.is_active, i.metadata, i.created_at, i.updated_at
|
||
|
|
FROM product_ingredients pi
|
||
|
|
LEFT JOIN products p ON pi.product_id = p.id
|
||
|
|
LEFT JOIN ingredients i ON pi.ingredient_id = i.id
|
||
|
|
WHERE pi.ingredient_id = $1 AND pi.organization_id = $2
|
||
|
|
ORDER BY pi.created_at DESC
|
||
|
|
`
|
||
|
|
|
||
|
|
rows, err := r.db.QueryContext(ctx, query, ingredientID, organizationID)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer rows.Close()
|
||
|
|
|
||
|
|
var productIngredients []*entities.ProductIngredient
|
||
|
|
for rows.Next() {
|
||
|
|
productIngredient := &entities.ProductIngredient{}
|
||
|
|
product := &entities.Product{}
|
||
|
|
ingredient := &entities.Ingredient{}
|
||
|
|
|
||
|
|
err := rows.Scan(
|
||
|
|
&productIngredient.ID,
|
||
|
|
&productIngredient.OrganizationID,
|
||
|
|
&productIngredient.OutletID,
|
||
|
|
&productIngredient.ProductID,
|
||
|
|
&productIngredient.IngredientID,
|
||
|
|
&productIngredient.Quantity,
|
||
|
|
&productIngredient.CreatedAt,
|
||
|
|
&productIngredient.UpdatedAt,
|
||
|
|
&product.ID,
|
||
|
|
&product.OrganizationID,
|
||
|
|
&product.CategoryID,
|
||
|
|
&product.SKU,
|
||
|
|
&product.Name,
|
||
|
|
&product.Description,
|
||
|
|
&product.Price,
|
||
|
|
&product.Cost,
|
||
|
|
&product.BusinessType,
|
||
|
|
&product.ImageURL,
|
||
|
|
&product.PrinterType,
|
||
|
|
&product.UnitID,
|
||
|
|
&product.HasIngredients,
|
||
|
|
&product.Metadata,
|
||
|
|
&product.IsActive,
|
||
|
|
&product.CreatedAt,
|
||
|
|
&product.UpdatedAt,
|
||
|
|
&ingredient.ID,
|
||
|
|
&ingredient.OrganizationID,
|
||
|
|
&ingredient.OutletID,
|
||
|
|
&ingredient.Name,
|
||
|
|
&ingredient.UnitID,
|
||
|
|
&ingredient.Cost,
|
||
|
|
&ingredient.Stock,
|
||
|
|
&ingredient.IsSemiFinished,
|
||
|
|
&ingredient.IsActive,
|
||
|
|
&ingredient.Metadata,
|
||
|
|
&ingredient.CreatedAt,
|
||
|
|
&ingredient.UpdatedAt,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
productIngredient.Product = product
|
||
|
|
productIngredient.Ingredient = ingredient
|
||
|
|
productIngredients = append(productIngredients, productIngredient)
|
||
|
|
}
|
||
|
|
|
||
|
|
return productIngredients, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *ProductIngredientRepository) Update(ctx context.Context, productIngredient *entities.ProductIngredient) error {
|
||
|
|
query := `
|
||
|
|
UPDATE product_ingredients
|
||
|
|
SET outlet_id = $1, quantity = $2, updated_at = $3
|
||
|
|
WHERE id = $4 AND organization_id = $5
|
||
|
|
`
|
||
|
|
|
||
|
|
result, err := r.db.ExecContext(ctx, query,
|
||
|
|
productIngredient.OutletID,
|
||
|
|
productIngredient.Quantity,
|
||
|
|
productIngredient.UpdatedAt,
|
||
|
|
productIngredient.ID,
|
||
|
|
productIngredient.OrganizationID,
|
||
|
|
)
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
rowsAffected, err := result.RowsAffected()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
if rowsAffected == 0 {
|
||
|
|
return sql.ErrNoRows
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *ProductIngredientRepository) Delete(ctx context.Context, id, organizationID uuid.UUID) error {
|
||
|
|
query := `DELETE FROM product_ingredients WHERE id = $1 AND organization_id = $2`
|
||
|
|
|
||
|
|
result, err := r.db.ExecContext(ctx, query, id, organizationID)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
rowsAffected, err := result.RowsAffected()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
if rowsAffected == 0 {
|
||
|
|
return sql.ErrNoRows
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *ProductIngredientRepository) DeleteByProductID(ctx context.Context, productID, organizationID uuid.UUID) error {
|
||
|
|
query := `DELETE FROM product_ingredients WHERE product_id = $1 AND organization_id = $2`
|
||
|
|
|
||
|
|
_, err := r.db.ExecContext(ctx, query, productID, organizationID)
|
||
|
|
return err
|
||
|
|
}
|