Add Customer users

This commit is contained in:
Aditya Siregar
2025-08-03 23:55:51 +07:00
parent 96743cf50b
commit 5741243425
69 changed files with 3005 additions and 158 deletions
@@ -0,0 +1,287 @@
package repository
import (
"apskel-pos-be/internal/entities"
"context"
"database/sql"
"github.com/google/uuid"
)
type IngredientCompositionRepository struct {
db *sql.DB
}
func NewIngredientCompositionRepository(db *sql.DB) *IngredientCompositionRepository {
return &IngredientCompositionRepository{db: db}
}
func (r *IngredientCompositionRepository) Create(ctx context.Context, composition *entities.IngredientComposition) error {
query := `
INSERT INTO ingredient_compositions (id, organization_id, outlet_id, parent_ingredient_id, child_ingredient_id, quantity, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
`
_, err := r.db.ExecContext(ctx, query,
composition.ID,
composition.OrganizationID,
composition.OutletID,
composition.ParentIngredientID,
composition.ChildIngredientID,
composition.Quantity,
composition.CreatedAt,
composition.UpdatedAt,
)
return err
}
func (r *IngredientCompositionRepository) GetByID(ctx context.Context, id, organizationID uuid.UUID) (*entities.IngredientComposition, error) {
query := `
SELECT ic.id, ic.organization_id, ic.outlet_id, ic.parent_ingredient_id, ic.child_ingredient_id, ic.quantity, ic.created_at, ic.updated_at,
pi.id, pi.organization_id, pi.outlet_id, pi.name, pi.unit_id, pi.cost, pi.stock, pi.is_semi_finished, pi.is_active, pi.metadata, pi.created_at, pi.updated_at,
ci.id, ci.organization_id, ci.outlet_id, ci.name, ci.unit_id, ci.cost, ci.stock, ci.is_semi_finished, ci.is_active, ci.metadata, ci.created_at, ci.updated_at
FROM ingredient_compositions ic
LEFT JOIN ingredients pi ON ic.parent_ingredient_id = pi.id
LEFT JOIN ingredients ci ON ic.child_ingredient_id = ci.id
WHERE ic.id = $1 AND ic.organization_id = $2
`
composition := &entities.IngredientComposition{}
parentIngredient := &entities.Ingredient{}
childIngredient := &entities.Ingredient{}
err := r.db.QueryRowContext(ctx, query, id, organizationID).Scan(
&composition.ID,
&composition.OrganizationID,
&composition.OutletID,
&composition.ParentIngredientID,
&composition.ChildIngredientID,
&composition.Quantity,
&composition.CreatedAt,
&composition.UpdatedAt,
&parentIngredient.ID,
&parentIngredient.OrganizationID,
&parentIngredient.OutletID,
&parentIngredient.Name,
&parentIngredient.UnitID,
&parentIngredient.Cost,
&parentIngredient.Stock,
&parentIngredient.IsSemiFinished,
&parentIngredient.IsActive,
&parentIngredient.Metadata,
&parentIngredient.CreatedAt,
&parentIngredient.UpdatedAt,
&childIngredient.ID,
&childIngredient.OrganizationID,
&childIngredient.OutletID,
&childIngredient.Name,
&childIngredient.UnitID,
&childIngredient.Cost,
&childIngredient.Stock,
&childIngredient.IsSemiFinished,
&childIngredient.IsActive,
&childIngredient.Metadata,
&childIngredient.CreatedAt,
&childIngredient.UpdatedAt,
)
if err != nil {
return nil, err
}
composition.ParentIngredient = parentIngredient
composition.ChildIngredient = childIngredient
return composition, nil
}
func (r *IngredientCompositionRepository) GetByParentIngredientID(ctx context.Context, parentIngredientID, organizationID uuid.UUID) ([]*entities.IngredientComposition, error) {
query := `
SELECT ic.id, ic.organization_id, ic.outlet_id, ic.parent_ingredient_id, ic.child_ingredient_id, ic.quantity, ic.created_at, ic.updated_at,
pi.id, pi.organization_id, pi.outlet_id, pi.name, pi.unit_id, pi.cost, pi.stock, pi.is_semi_finished, pi.is_active, pi.metadata, pi.created_at, pi.updated_at,
ci.id, ci.organization_id, ci.outlet_id, ci.name, ci.unit_id, ci.cost, ci.stock, ci.is_semi_finished, ci.is_active, ci.metadata, ci.created_at, ci.updated_at
FROM ingredient_compositions ic
LEFT JOIN ingredients pi ON ic.parent_ingredient_id = pi.id
LEFT JOIN ingredients ci ON ic.child_ingredient_id = ci.id
WHERE ic.parent_ingredient_id = $1 AND ic.organization_id = $2
ORDER BY ic.created_at DESC
`
rows, err := r.db.QueryContext(ctx, query, parentIngredientID, organizationID)
if err != nil {
return nil, err
}
defer rows.Close()
var compositions []*entities.IngredientComposition
for rows.Next() {
composition := &entities.IngredientComposition{}
parentIngredient := &entities.Ingredient{}
childIngredient := &entities.Ingredient{}
err := rows.Scan(
&composition.ID,
&composition.OrganizationID,
&composition.OutletID,
&composition.ParentIngredientID,
&composition.ChildIngredientID,
&composition.Quantity,
&composition.CreatedAt,
&composition.UpdatedAt,
&parentIngredient.ID,
&parentIngredient.OrganizationID,
&parentIngredient.OutletID,
&parentIngredient.Name,
&parentIngredient.UnitID,
&parentIngredient.Cost,
&parentIngredient.Stock,
&parentIngredient.IsSemiFinished,
&parentIngredient.IsActive,
&parentIngredient.Metadata,
&parentIngredient.CreatedAt,
&parentIngredient.UpdatedAt,
&childIngredient.ID,
&childIngredient.OrganizationID,
&childIngredient.OutletID,
&childIngredient.Name,
&childIngredient.UnitID,
&childIngredient.Cost,
&childIngredient.Stock,
&childIngredient.IsSemiFinished,
&childIngredient.IsActive,
&childIngredient.Metadata,
&childIngredient.CreatedAt,
&childIngredient.UpdatedAt,
)
if err != nil {
return nil, err
}
composition.ParentIngredient = parentIngredient
composition.ChildIngredient = childIngredient
compositions = append(compositions, composition)
}
return compositions, nil
}
func (r *IngredientCompositionRepository) GetByChildIngredientID(ctx context.Context, childIngredientID, organizationID uuid.UUID) ([]*entities.IngredientComposition, error) {
query := `
SELECT ic.id, ic.organization_id, ic.outlet_id, ic.parent_ingredient_id, ic.child_ingredient_id, ic.quantity, ic.created_at, ic.updated_at,
pi.id, pi.organization_id, pi.outlet_id, pi.name, pi.unit_id, pi.cost, pi.stock, pi.is_semi_finished, pi.is_active, pi.metadata, pi.created_at, pi.updated_at,
ci.id, ci.organization_id, ci.outlet_id, ci.name, ci.unit_id, ci.cost, ci.stock, ci.is_semi_finished, ci.is_active, ci.metadata, ci.created_at, ci.updated_at
FROM ingredient_compositions ic
LEFT JOIN ingredients pi ON ic.parent_ingredient_id = pi.id
LEFT JOIN ingredients ci ON ic.child_ingredient_id = ci.id
WHERE ic.child_ingredient_id = $1 AND ic.organization_id = $2
ORDER BY ic.created_at DESC
`
rows, err := r.db.QueryContext(ctx, query, childIngredientID, organizationID)
if err != nil {
return nil, err
}
defer rows.Close()
var compositions []*entities.IngredientComposition
for rows.Next() {
composition := &entities.IngredientComposition{}
parentIngredient := &entities.Ingredient{}
childIngredient := &entities.Ingredient{}
err := rows.Scan(
&composition.ID,
&composition.OrganizationID,
&composition.OutletID,
&composition.ParentIngredientID,
&composition.ChildIngredientID,
&composition.Quantity,
&composition.CreatedAt,
&composition.UpdatedAt,
&parentIngredient.ID,
&parentIngredient.OrganizationID,
&parentIngredient.OutletID,
&parentIngredient.Name,
&parentIngredient.UnitID,
&parentIngredient.Cost,
&parentIngredient.Stock,
&parentIngredient.IsSemiFinished,
&parentIngredient.IsActive,
&parentIngredient.Metadata,
&parentIngredient.CreatedAt,
&parentIngredient.UpdatedAt,
&childIngredient.ID,
&childIngredient.OrganizationID,
&childIngredient.OutletID,
&childIngredient.Name,
&childIngredient.UnitID,
&childIngredient.Cost,
&childIngredient.Stock,
&childIngredient.IsSemiFinished,
&childIngredient.IsActive,
&childIngredient.Metadata,
&childIngredient.CreatedAt,
&childIngredient.UpdatedAt,
)
if err != nil {
return nil, err
}
composition.ParentIngredient = parentIngredient
composition.ChildIngredient = childIngredient
compositions = append(compositions, composition)
}
return compositions, nil
}
func (r *IngredientCompositionRepository) Update(ctx context.Context, composition *entities.IngredientComposition) error {
query := `
UPDATE ingredient_compositions
SET outlet_id = $1, quantity = $2, updated_at = $3
WHERE id = $4 AND organization_id = $5
`
result, err := r.db.ExecContext(ctx, query,
composition.OutletID,
composition.Quantity,
composition.UpdatedAt,
composition.ID,
composition.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 *IngredientCompositionRepository) Delete(ctx context.Context, id, organizationID uuid.UUID) error {
query := `DELETE FROM ingredient_compositions 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
}
@@ -0,0 +1,102 @@
package repository
import (
"apskel-pos-be/internal/entities"
"context"
"fmt"
"gorm.io/gorm"
"github.com/google/uuid"
)
type IngredientRepository struct {
db *gorm.DB
}
func NewIngredientRepository(db *gorm.DB) *IngredientRepository {
return &IngredientRepository{db: db}
}
func (r *IngredientRepository) Create(ctx context.Context, ingredient *entities.Ingredient) error {
return r.db.WithContext(ctx).Create(ingredient).Error
}
func (r *IngredientRepository) GetByID(ctx context.Context, id, organizationID uuid.UUID) (*entities.Ingredient, error) {
var ingredient entities.Ingredient
err := r.db.WithContext(ctx).Preload("Unit").Where("id = ? AND organization_id = ?", id, organizationID).First(&ingredient).Error
if err != nil {
return nil, err
}
return &ingredient, nil
}
func (r *IngredientRepository) GetAll(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID, page, limit int, search string, isSemiFinished *bool) ([]*entities.Ingredient, int, error) {
var ingredients []*entities.Ingredient
var total int64
query := r.db.WithContext(ctx).Model(&entities.Ingredient{}).Where("organization_id = ?", organizationID)
if outletID != nil {
query = query.Where("outlet_id = ?", *outletID)
}
if search != "" {
searchValue := "%" + search + "%"
query = query.Where("name ILIKE ?", searchValue)
}
if isSemiFinished != nil {
query = query.Where("is_semi_finished = ?", *isSemiFinished)
}
// Count total records
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// Get paginated results with Unit preloaded
offset := (page - 1) * limit
err := query.Preload("Unit").Order("created_at DESC").Limit(limit).Offset(offset).Find(&ingredients).Error
if err != nil {
return nil, 0, err
}
return ingredients, int(total), nil
}
func (r *IngredientRepository) Update(ctx context.Context, ingredient *entities.Ingredient) error {
result := r.db.WithContext(ctx).Where("id = ? AND organization_id = ?", ingredient.ID, ingredient.OrganizationID).Save(ingredient)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("no rows affected")
}
return nil
}
func (r *IngredientRepository) UpdateStock(ctx context.Context, id uuid.UUID, quantity float64, organizationID uuid.UUID) error {
result := r.db.WithContext(ctx).Model(&entities.Ingredient{}).
Where("id = ? AND organization_id = ?", id, organizationID).
Update("stock", gorm.Expr("stock + ?", quantity))
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("no rows affected")
}
return nil
}
func (r *IngredientRepository) Delete(ctx context.Context, id, organizationID uuid.UUID) error {
result := r.db.WithContext(ctx).Where("id = ? AND organization_id = ?", id, organizationID).Delete(&entities.Ingredient{})
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("no rows affected")
}
return nil
}
+10 -8
View File
@@ -150,11 +150,12 @@ func (r *PaymentRepositoryImpl) CreatePaymentWithInventoryMovement(ctx context.C
movement := &entities.InventoryMovement{
OrganizationID: order.OrganizationID,
OutletID: order.OutletID,
ProductID: item.ProductID,
ItemID: item.ProductID,
ItemType: "PRODUCT",
MovementType: entities.InventoryMovementTypeSale,
Quantity: -item.Quantity,
PreviousQuantity: updatedInventory.Quantity + item.Quantity, // Add back the quantity that was subtracted
NewQuantity: updatedInventory.Quantity,
Quantity: float64(-item.Quantity),
PreviousQuantity: float64(updatedInventory.Quantity + item.Quantity), // Add back the quantity that was subtracted
NewQuantity: float64(updatedInventory.Quantity),
UnitCost: item.UnitCost,
TotalCost: float64(item.Quantity) * item.UnitCost,
ReferenceType: func() *entities.InventoryMovementReferenceType {
@@ -222,11 +223,12 @@ func (r *PaymentRepositoryImpl) RefundPaymentWithInventoryMovement(ctx context.C
movement := &entities.InventoryMovement{
OrganizationID: order.OrganizationID,
OutletID: order.OutletID,
ProductID: item.ProductID,
ItemID: item.ProductID,
ItemType: "PRODUCT",
MovementType: entities.InventoryMovementTypeRefund,
Quantity: refundedQuantity,
PreviousQuantity: updatedInventory.Quantity - refundedQuantity, // Subtract the quantity that was added
NewQuantity: updatedInventory.Quantity,
Quantity: float64(refundedQuantity),
PreviousQuantity: float64(updatedInventory.Quantity - refundedQuantity), // Subtract the quantity that was added
NewQuantity: float64(updatedInventory.Quantity),
UnitCost: item.UnitCost,
TotalCost: float64(refundedQuantity) * item.UnitCost,
ReferenceType: func() *entities.InventoryMovementReferenceType {
@@ -0,0 +1,309 @@
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
}
+84
View File
@@ -0,0 +1,84 @@
package repository
import (
"apskel-pos-be/internal/entities"
"context"
"fmt"
"gorm.io/gorm"
"github.com/google/uuid"
)
type UnitRepository struct {
db *gorm.DB
}
func NewUnitRepository(db *gorm.DB) *UnitRepository {
return &UnitRepository{db: db}
}
func (r *UnitRepository) Create(ctx context.Context, unit *entities.Unit) error {
return r.db.WithContext(ctx).Create(unit).Error
}
func (r *UnitRepository) GetByID(ctx context.Context, id, organizationID uuid.UUID) (*entities.Unit, error) {
var unit entities.Unit
err := r.db.WithContext(ctx).Where("id = ? AND organization_id = ?", id, organizationID).First(&unit).Error
if err != nil {
return nil, err
}
return &unit, nil
}
func (r *UnitRepository) GetAll(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID, page, limit int, search string) ([]*entities.Unit, int, error) {
var units []*entities.Unit
var total int64
query := r.db.WithContext(ctx).Model(&entities.Unit{}).Where("organization_id = ?", organizationID)
if outletID != nil {
query = query.Where("outlet_id = ?", *outletID)
}
if search != "" {
searchValue := "%" + search + "%"
query = query.Where("name ILIKE ? OR abbreviation ILIKE ?", searchValue, searchValue)
}
// Count total records
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// Get paginated results
offset := (page - 1) * limit
err := query.Order("created_at DESC").Limit(limit).Offset(offset).Find(&units).Error
if err != nil {
return nil, 0, err
}
return units, int(total), nil
}
func (r *UnitRepository) Update(ctx context.Context, unit *entities.Unit) error {
result := r.db.WithContext(ctx).Where("id = ? AND organization_id = ?", unit.ID, unit.OrganizationID).Save(unit)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("no rows affected")
}
return nil
}
func (r *UnitRepository) Delete(ctx context.Context, id, organizationID uuid.UUID) error {
result := r.db.WithContext(ctx).Where("id = ? AND organization_id = ?", id, organizationID).Delete(&entities.Unit{})
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("no rows affected")
}
return nil
}