Add coa purchase and vendors
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user