177 lines
7.0 KiB
Go
177 lines
7.0 KiB
Go
package repository
|
|
|
|
import (
|
|
"apskel-pos-be/internal/entities"
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type IngredientUnitConverterRepository interface {
|
|
Create(ctx context.Context, converter *entities.IngredientUnitConverter) error
|
|
GetByID(ctx context.Context, id, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error)
|
|
GetByIDAndOrganizationID(ctx context.Context, id, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error)
|
|
Update(ctx context.Context, converter *entities.IngredientUnitConverter) error
|
|
Delete(ctx context.Context, id, organizationID uuid.UUID) error
|
|
List(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, page, limit int) ([]*entities.IngredientUnitConverter, int, error)
|
|
GetByIngredientAndUnits(ctx context.Context, ingredientID, fromUnitID, toUnitID, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error)
|
|
GetConvertersForIngredient(ctx context.Context, ingredientID, organizationID uuid.UUID) ([]*entities.IngredientUnitConverter, error)
|
|
GetActiveConverters(ctx context.Context, organizationID uuid.UUID) ([]*entities.IngredientUnitConverter, error)
|
|
ConvertQuantity(ctx context.Context, ingredientID, fromUnitID, toUnitID, organizationID uuid.UUID, quantity float64) (float64, error)
|
|
}
|
|
|
|
type IngredientUnitConverterRepositoryImpl struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewIngredientUnitConverterRepositoryImpl(db *gorm.DB) IngredientUnitConverterRepository {
|
|
return &IngredientUnitConverterRepositoryImpl{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) Create(ctx context.Context, converter *entities.IngredientUnitConverter) error {
|
|
return r.db.WithContext(ctx).Create(converter).Error
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) GetByID(ctx context.Context, id, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error) {
|
|
var converter entities.IngredientUnitConverter
|
|
err := r.db.WithContext(ctx).
|
|
Where("id = ? AND organization_id = ?", id, organizationID).
|
|
Preload("Ingredient").
|
|
Preload("FromUnit").
|
|
Preload("ToUnit").
|
|
Preload("CreatedByUser").
|
|
Preload("UpdatedByUser").
|
|
First(&converter).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &converter, nil
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) GetByIDAndOrganizationID(ctx context.Context, id, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error) {
|
|
return r.GetByID(ctx, id, organizationID)
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) Update(ctx context.Context, converter *entities.IngredientUnitConverter) error {
|
|
return r.db.WithContext(ctx).Save(converter).Error
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) Delete(ctx context.Context, id, organizationID uuid.UUID) error {
|
|
return r.db.WithContext(ctx).
|
|
Where("id = ? AND organization_id = ?", id, organizationID).
|
|
Delete(&entities.IngredientUnitConverter{}).Error
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) List(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, page, limit int) ([]*entities.IngredientUnitConverter, int, error) {
|
|
var converters []*entities.IngredientUnitConverter
|
|
var total int64
|
|
|
|
query := r.db.WithContext(ctx).
|
|
Model(&entities.IngredientUnitConverter{}).
|
|
Where("organization_id = ?", organizationID)
|
|
|
|
// Apply filters
|
|
if ingredientID, ok := filters["ingredient_id"].(uuid.UUID); ok {
|
|
query = query.Where("ingredient_id = ?", ingredientID)
|
|
}
|
|
if fromUnitID, ok := filters["from_unit_id"].(uuid.UUID); ok {
|
|
query = query.Where("from_unit_id = ?", fromUnitID)
|
|
}
|
|
if toUnitID, ok := filters["to_unit_id"].(uuid.UUID); ok {
|
|
query = query.Where("to_unit_id = ?", toUnitID)
|
|
}
|
|
if isActive, ok := filters["is_active"].(bool); ok {
|
|
query = query.Where("is_active = ?", isActive)
|
|
}
|
|
if search, ok := filters["search"].(string); ok && search != "" {
|
|
query = query.Joins("LEFT JOIN ingredients ON ingredient_unit_converters.ingredient_id = ingredients.id").
|
|
Joins("LEFT JOIN units AS from_units ON ingredient_unit_converters.from_unit_id = from_units.id").
|
|
Joins("LEFT JOIN units AS to_units ON ingredient_unit_converters.to_unit_id = to_units.id").
|
|
Where("ingredients.name ILIKE ? OR from_units.name ILIKE ? OR to_units.name ILIKE ?",
|
|
"%"+search+"%", "%"+search+"%", "%"+search+"%")
|
|
}
|
|
|
|
// Get total count
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Apply pagination and get results
|
|
offset := (page - 1) * limit
|
|
err := query.
|
|
Preload("Ingredient").
|
|
Preload("FromUnit").
|
|
Preload("ToUnit").
|
|
Preload("CreatedByUser").
|
|
Preload("UpdatedByUser").
|
|
Order("created_at DESC").
|
|
Offset(offset).
|
|
Limit(limit).
|
|
Find(&converters).Error
|
|
|
|
return converters, int(total), err
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) GetByIngredientAndUnits(ctx context.Context, ingredientID, fromUnitID, toUnitID, organizationID uuid.UUID) (*entities.IngredientUnitConverter, error) {
|
|
var converter entities.IngredientUnitConverter
|
|
err := r.db.WithContext(ctx).
|
|
Where("ingredient_id = ? AND from_unit_id = ? AND to_unit_id = ? AND organization_id = ? AND is_active = ?",
|
|
ingredientID, fromUnitID, toUnitID, organizationID, true).
|
|
Preload("Ingredient").
|
|
Preload("FromUnit").
|
|
Preload("ToUnit").
|
|
First(&converter).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &converter, nil
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) GetConvertersForIngredient(ctx context.Context, ingredientID, organizationID uuid.UUID) ([]*entities.IngredientUnitConverter, error) {
|
|
var converters []*entities.IngredientUnitConverter
|
|
err := r.db.WithContext(ctx).
|
|
Where("ingredient_id = ? AND organization_id = ? AND is_active = ?", ingredientID, organizationID, true).
|
|
Preload("FromUnit").
|
|
Preload("ToUnit").
|
|
Find(&converters).Error
|
|
return converters, err
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) GetActiveConverters(ctx context.Context, organizationID uuid.UUID) ([]*entities.IngredientUnitConverter, error) {
|
|
var converters []*entities.IngredientUnitConverter
|
|
err := r.db.WithContext(ctx).
|
|
Where("organization_id = ? AND is_active = ?", organizationID, true).
|
|
Preload("Ingredient").
|
|
Preload("FromUnit").
|
|
Preload("ToUnit").
|
|
Find(&converters).Error
|
|
return converters, err
|
|
}
|
|
|
|
func (r *IngredientUnitConverterRepositoryImpl) ConvertQuantity(ctx context.Context, ingredientID, fromUnitID, toUnitID, organizationID uuid.UUID, quantity float64) (float64, error) {
|
|
// If from and to units are the same, return the same quantity
|
|
if fromUnitID == toUnitID {
|
|
return quantity, nil
|
|
}
|
|
|
|
// Try to find direct converter
|
|
converter, err := r.GetByIngredientAndUnits(ctx, ingredientID, fromUnitID, toUnitID, organizationID)
|
|
if err == nil {
|
|
return quantity * converter.ConversionFactor, nil
|
|
}
|
|
|
|
// If direct converter not found, try to find reverse converter
|
|
reverseConverter, err := r.GetByIngredientAndUnits(ctx, ingredientID, toUnitID, fromUnitID, organizationID)
|
|
if err == nil {
|
|
return quantity / reverseConverter.ConversionFactor, nil
|
|
}
|
|
|
|
// If no converter found, return error
|
|
return 0, fmt.Errorf("no conversion found between units %s and %s for ingredient %s", fromUnitID, toUnitID, ingredientID)
|
|
}
|
|
|