apskel-pos-backend/internal/repository/inventory_movement_repository.go

194 lines
6.7 KiB
Go
Raw Normal View History

2025-07-30 23:18:20 +07:00
package repository
import (
"context"
"apskel-pos-be/internal/entities"
"github.com/google/uuid"
"gorm.io/gorm"
)
type InventoryMovementRepository interface {
Create(ctx context.Context, movement *entities.InventoryMovement) error
GetByID(ctx context.Context, id uuid.UUID) (*entities.InventoryMovement, error)
GetWithRelations(ctx context.Context, id uuid.UUID) (*entities.InventoryMovement, error)
List(ctx context.Context, filters map[string]interface{}, limit, offset int) ([]*entities.InventoryMovement, int64, error)
GetByProductAndOutlet(ctx context.Context, productID, outletID uuid.UUID, limit, offset int) ([]*entities.InventoryMovement, int64, error)
GetByOrderID(ctx context.Context, orderID uuid.UUID) ([]*entities.InventoryMovement, error)
GetByPaymentID(ctx context.Context, paymentID uuid.UUID) ([]*entities.InventoryMovement, error)
Count(ctx context.Context, filters map[string]interface{}) (int64, error)
CreateWithTransaction(tx *gorm.DB, movement *entities.InventoryMovement) error
2025-08-13 23:14:26 +07:00
CreateInBatches(ctx context.Context, movements []*entities.InventoryMovement, batchSize int) error
2025-07-30 23:18:20 +07:00
}
type InventoryMovementRepositoryImpl struct {
db *gorm.DB
}
func NewInventoryMovementRepositoryImpl(db *gorm.DB) *InventoryMovementRepositoryImpl {
return &InventoryMovementRepositoryImpl{
db: db,
}
}
func (r *InventoryMovementRepositoryImpl) Create(ctx context.Context, movement *entities.InventoryMovement) error {
return r.db.WithContext(ctx).Create(movement).Error
}
func (r *InventoryMovementRepositoryImpl) CreateWithTransaction(tx *gorm.DB, movement *entities.InventoryMovement) error {
return tx.Create(movement).Error
}
2025-08-13 23:14:26 +07:00
func (r *InventoryMovementRepositoryImpl) CreateInBatches(ctx context.Context, movements []*entities.InventoryMovement, batchSize int) error {
if len(movements) == 0 {
return nil
}
return r.db.WithContext(ctx).CreateInBatches(movements, batchSize).Error
}
2025-07-30 23:18:20 +07:00
func (r *InventoryMovementRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.InventoryMovement, error) {
var movement entities.InventoryMovement
err := r.db.WithContext(ctx).First(&movement, "id = ?", id).Error
if err != nil {
return nil, err
}
return &movement, nil
}
func (r *InventoryMovementRepositoryImpl) GetWithRelations(ctx context.Context, id uuid.UUID) (*entities.InventoryMovement, error) {
var movement entities.InventoryMovement
err := r.db.WithContext(ctx).
Preload("Organization").
Preload("Outlet").
Preload("Product").
Preload("Product.Category").
Preload("Order").
Preload("Payment").
Preload("User").
First(&movement, "id = ?", id).Error
if err != nil {
return nil, err
}
return &movement, nil
}
func (r *InventoryMovementRepositoryImpl) List(ctx context.Context, filters map[string]interface{}, limit, offset int) ([]*entities.InventoryMovement, int64, error) {
var movements []*entities.InventoryMovement
var total int64
query := r.db.WithContext(ctx).Model(&entities.InventoryMovement{}).
Preload("Product").
Preload("Product.Category").
Preload("Outlet").
Preload("Order").
Preload("Payment").
Preload("User")
for key, value := range filters {
switch key {
case "search":
searchValue := "%" + value.(string) + "%"
query = query.Joins("JOIN products ON inventory_movements.product_id = products.id").
Where("products.name ILIKE ? OR inventory_movements.reason ILIKE ?", searchValue, searchValue)
case "date_from":
query = query.Where("created_at >= ?", value)
case "date_to":
query = query.Where("created_at <= ?", value)
case "movement_type":
query = query.Where("movement_type = ?", value)
case "reference_type":
query = query.Where("reference_type = ?", value)
default:
query = query.Where(key+" = ?", value)
}
}
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
err := query.Order("created_at DESC").Limit(limit).Offset(offset).Find(&movements).Error
return movements, total, err
}
func (r *InventoryMovementRepositoryImpl) GetByProductAndOutlet(ctx context.Context, productID, outletID uuid.UUID, limit, offset int) ([]*entities.InventoryMovement, int64, error) {
var movements []*entities.InventoryMovement
var total int64
query := r.db.WithContext(ctx).Model(&entities.InventoryMovement{}).
Preload("Product").
Preload("Product.Category").
Preload("Order").
Preload("Payment").
Preload("User").
Where("product_id = ? AND outlet_id = ?", productID, outletID)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
err := query.Order("created_at DESC").Limit(limit).Offset(offset).Find(&movements).Error
return movements, total, err
}
func (r *InventoryMovementRepositoryImpl) GetByOrderID(ctx context.Context, orderID uuid.UUID) ([]*entities.InventoryMovement, error) {
var movements []*entities.InventoryMovement
err := r.db.WithContext(ctx).
Preload("Product").
Preload("Product.Category").
Where("order_id = ?", orderID).
Order("created_at DESC").
Find(&movements).Error
return movements, err
}
func (r *InventoryMovementRepositoryImpl) GetByPaymentID(ctx context.Context, paymentID uuid.UUID) ([]*entities.InventoryMovement, error) {
var movements []*entities.InventoryMovement
err := r.db.WithContext(ctx).
Preload("Product").
Preload("Product.Category").
Where("payment_id = ?", paymentID).
Order("created_at DESC").
Find(&movements).Error
return movements, err
}
func (r *InventoryMovementRepositoryImpl) GetByReference(ctx context.Context, referenceType entities.InventoryMovementReferenceType, referenceID uuid.UUID) ([]*entities.InventoryMovement, error) {
var movements []*entities.InventoryMovement
err := r.db.WithContext(ctx).
Preload("Product").
Preload("Product.Category").
Where("reference_type = ? AND reference_id = ?", referenceType, referenceID).
Order("created_at DESC").
Find(&movements).Error
return movements, err
}
func (r *InventoryMovementRepositoryImpl) Count(ctx context.Context, filters map[string]interface{}) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.InventoryMovement{})
for key, value := range filters {
switch key {
case "search":
searchValue := "%" + value.(string) + "%"
query = query.Joins("JOIN products ON inventory_movements.product_id = products.id").
Where("products.name ILIKE ? OR inventory_movements.reason ILIKE ?", searchValue, searchValue)
case "date_from":
query = query.Where("created_at >= ?", value)
case "date_to":
query = query.Where("created_at <= ?", value)
case "movement_type":
query = query.Where("movement_type = ?", value)
case "reference_type":
query = query.Where("reference_type = ?", value)
default:
query = query.Where(key+" = ?", value)
}
}
err := query.Count(&count).Error
return count, err
}