Add coa purchase and vendors
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type AccountRepository interface {
|
||||
Create(ctx context.Context, account *entities.Account) error
|
||||
GetByID(ctx context.Context, id uuid.UUID) (*entities.Account, error)
|
||||
Update(ctx context.Context, account *entities.Account) error
|
||||
Delete(ctx context.Context, id uuid.UUID) error
|
||||
List(ctx context.Context, req *entities.Account) ([]*entities.Account, int, error)
|
||||
GetByOrganization(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.Account, error)
|
||||
GetByChartOfAccount(ctx context.Context, chartOfAccountID uuid.UUID) ([]*entities.Account, error)
|
||||
GetByNumber(ctx context.Context, organizationID uuid.UUID, number string, outletID *uuid.UUID) (*entities.Account, error)
|
||||
UpdateBalance(ctx context.Context, id uuid.UUID, amount float64) error
|
||||
GetBalance(ctx context.Context, id uuid.UUID) (float64, error)
|
||||
GetSystemAccounts(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.Account, error)
|
||||
}
|
||||
|
||||
type AccountRepositoryImpl struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewAccountRepositoryImpl(db *gorm.DB) *AccountRepositoryImpl {
|
||||
return &AccountRepositoryImpl{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) Create(ctx context.Context, account *entities.Account) error {
|
||||
return r.db.WithContext(ctx).Create(account).Error
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.Account, error) {
|
||||
var account entities.Account
|
||||
err := r.db.WithContext(ctx).Preload("ChartOfAccount").Preload("ChartOfAccount.ChartOfAccountType").First(&account, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) Update(ctx context.Context, account *entities.Account) error {
|
||||
return r.db.WithContext(ctx).Save(account).Error
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.Account{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) List(ctx context.Context, req *entities.Account) ([]*entities.Account, int, error) {
|
||||
var accounts []*entities.Account
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.Account{})
|
||||
|
||||
// Apply filters
|
||||
if req.OrganizationID != uuid.Nil {
|
||||
query = query.Where("organization_id = ?", req.OrganizationID)
|
||||
}
|
||||
if req.OutletID != nil {
|
||||
query = query.Where("outlet_id = ?", *req.OutletID)
|
||||
}
|
||||
if req.ChartOfAccountID != uuid.Nil {
|
||||
query = query.Where("chart_of_account_id = ?", req.ChartOfAccountID)
|
||||
}
|
||||
if req.AccountType != "" {
|
||||
query = query.Where("account_type = ?", req.AccountType)
|
||||
}
|
||||
|
||||
// Count total
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Apply pagination and preloads
|
||||
err := query.Preload("ChartOfAccount").Preload("ChartOfAccount.ChartOfAccountType").Find(&accounts).Error
|
||||
return accounts, int(total), err
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) GetByOrganization(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.Account, error) {
|
||||
var accounts []*entities.Account
|
||||
query := r.db.WithContext(ctx).Where("organization_id = ?", organizationID)
|
||||
|
||||
if outletID != nil {
|
||||
query = query.Where("outlet_id = ?", *outletID)
|
||||
} else {
|
||||
query = query.Where("outlet_id IS NULL")
|
||||
}
|
||||
|
||||
err := query.Preload("ChartOfAccount").Preload("ChartOfAccount.ChartOfAccountType").Find(&accounts).Error
|
||||
return accounts, err
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) GetByChartOfAccount(ctx context.Context, chartOfAccountID uuid.UUID) ([]*entities.Account, error) {
|
||||
var accounts []*entities.Account
|
||||
err := r.db.WithContext(ctx).Where("chart_of_account_id = ?", chartOfAccountID).Preload("ChartOfAccount").Preload("ChartOfAccount.ChartOfAccountType").Find(&accounts).Error
|
||||
return accounts, err
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) GetByNumber(ctx context.Context, organizationID uuid.UUID, number string, outletID *uuid.UUID) (*entities.Account, error) {
|
||||
var account entities.Account
|
||||
query := r.db.WithContext(ctx).Where("organization_id = ? AND number = ?", organizationID, number)
|
||||
|
||||
if outletID != nil {
|
||||
query = query.Where("outlet_id = ?", *outletID)
|
||||
} else {
|
||||
query = query.Where("outlet_id IS NULL")
|
||||
}
|
||||
|
||||
err := query.Preload("ChartOfAccount").Preload("ChartOfAccount.ChartOfAccountType").First(&account).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) UpdateBalance(ctx context.Context, id uuid.UUID, amount float64) error {
|
||||
return r.db.WithContext(ctx).Model(&entities.Account{}).Where("id = ?", id).Update("current_balance", amount).Error
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) GetBalance(ctx context.Context, id uuid.UUID) (float64, error) {
|
||||
var balance float64
|
||||
err := r.db.WithContext(ctx).Model(&entities.Account{}).Select("current_balance").Where("id = ?", id).Scan(&balance).Error
|
||||
return balance, err
|
||||
}
|
||||
|
||||
func (r *AccountRepositoryImpl) GetSystemAccounts(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.Account, error) {
|
||||
var accounts []*entities.Account
|
||||
query := r.db.WithContext(ctx).Where("organization_id = ? AND is_system = ?", organizationID, true)
|
||||
|
||||
if outletID != nil {
|
||||
query = query.Where("outlet_id = ?", *outletID)
|
||||
} else {
|
||||
query = query.Where("outlet_id IS NULL")
|
||||
}
|
||||
|
||||
err := query.Preload("ChartOfAccount").Preload("ChartOfAccount.ChartOfAccountType").Find(&accounts).Error
|
||||
return accounts, err
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ChartOfAccountRepository interface {
|
||||
Create(ctx context.Context, chartOfAccount *entities.ChartOfAccount) error
|
||||
GetByID(ctx context.Context, id uuid.UUID) (*entities.ChartOfAccount, error)
|
||||
Update(ctx context.Context, chartOfAccount *entities.ChartOfAccount) error
|
||||
Delete(ctx context.Context, id uuid.UUID) error
|
||||
List(ctx context.Context, req *entities.ChartOfAccount) ([]*entities.ChartOfAccount, int, error)
|
||||
GetByOrganization(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.ChartOfAccount, error)
|
||||
GetByType(ctx context.Context, organizationID uuid.UUID, chartOfAccountTypeID uuid.UUID, outletID *uuid.UUID) ([]*entities.ChartOfAccount, error)
|
||||
GetByCode(ctx context.Context, organizationID uuid.UUID, code string, outletID *uuid.UUID) (*entities.ChartOfAccount, error)
|
||||
GetSystemAccounts(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.ChartOfAccount, error)
|
||||
}
|
||||
|
||||
type ChartOfAccountRepositoryImpl struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewChartOfAccountRepositoryImpl(db *gorm.DB) *ChartOfAccountRepositoryImpl {
|
||||
return &ChartOfAccountRepositoryImpl{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) Create(ctx context.Context, chartOfAccount *entities.ChartOfAccount) error {
|
||||
return r.db.WithContext(ctx).Create(chartOfAccount).Error
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.ChartOfAccount, error) {
|
||||
var chartOfAccount entities.ChartOfAccount
|
||||
err := r.db.WithContext(ctx).Preload("ChartOfAccountType").Preload("Parent").Preload("Children").First(&chartOfAccount, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &chartOfAccount, nil
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) Update(ctx context.Context, chartOfAccount *entities.ChartOfAccount) error {
|
||||
return r.db.WithContext(ctx).Save(chartOfAccount).Error
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.ChartOfAccount{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) List(ctx context.Context, req *entities.ChartOfAccount) ([]*entities.ChartOfAccount, int, error) {
|
||||
var chartOfAccounts []*entities.ChartOfAccount
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.ChartOfAccount{})
|
||||
|
||||
// Apply filters
|
||||
if req.OrganizationID != uuid.Nil {
|
||||
query = query.Where("organization_id = ?", req.OrganizationID)
|
||||
}
|
||||
if req.OutletID != nil {
|
||||
query = query.Where("outlet_id = ?", *req.OutletID)
|
||||
}
|
||||
if req.ChartOfAccountTypeID != uuid.Nil {
|
||||
query = query.Where("chart_of_account_type_id = ?", req.ChartOfAccountTypeID)
|
||||
}
|
||||
if req.ParentID != nil {
|
||||
query = query.Where("parent_id = ?", *req.ParentID)
|
||||
}
|
||||
|
||||
// Count total
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Apply pagination and preloads
|
||||
err := query.Preload("ChartOfAccountType").Preload("Parent").Preload("Children").Find(&chartOfAccounts).Error
|
||||
return chartOfAccounts, int(total), err
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) GetByOrganization(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.ChartOfAccount, error) {
|
||||
var chartOfAccounts []*entities.ChartOfAccount
|
||||
query := r.db.WithContext(ctx).Where("organization_id = ?", organizationID)
|
||||
|
||||
if outletID != nil {
|
||||
query = query.Where("outlet_id = ?", *outletID)
|
||||
} else {
|
||||
query = query.Where("outlet_id IS NULL")
|
||||
}
|
||||
|
||||
err := query.Preload("ChartOfAccountType").Preload("Parent").Preload("Children").Find(&chartOfAccounts).Error
|
||||
return chartOfAccounts, err
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) GetByType(ctx context.Context, organizationID uuid.UUID, chartOfAccountTypeID uuid.UUID, outletID *uuid.UUID) ([]*entities.ChartOfAccount, error) {
|
||||
var chartOfAccounts []*entities.ChartOfAccount
|
||||
query := r.db.WithContext(ctx).Where("organization_id = ? AND chart_of_account_type_id = ?", organizationID, chartOfAccountTypeID)
|
||||
|
||||
if outletID != nil {
|
||||
query = query.Where("outlet_id = ?", *outletID)
|
||||
} else {
|
||||
query = query.Where("outlet_id IS NULL")
|
||||
}
|
||||
|
||||
err := query.Preload("ChartOfAccountType").Preload("Parent").Preload("Children").Find(&chartOfAccounts).Error
|
||||
return chartOfAccounts, err
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) GetByCode(ctx context.Context, organizationID uuid.UUID, code string, outletID *uuid.UUID) (*entities.ChartOfAccount, error) {
|
||||
var chartOfAccount entities.ChartOfAccount
|
||||
query := r.db.WithContext(ctx).Where("organization_id = ? AND code = ?", organizationID, code)
|
||||
|
||||
if outletID != nil {
|
||||
query = query.Where("outlet_id = ?", *outletID)
|
||||
} else {
|
||||
query = query.Where("outlet_id IS NULL")
|
||||
}
|
||||
|
||||
err := query.Preload("ChartOfAccountType").Preload("Parent").First(&chartOfAccount).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &chartOfAccount, nil
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountRepositoryImpl) GetSystemAccounts(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID) ([]*entities.ChartOfAccount, error) {
|
||||
var chartOfAccounts []*entities.ChartOfAccount
|
||||
query := r.db.WithContext(ctx).Where("organization_id = ? AND is_system = ?", organizationID, true)
|
||||
|
||||
if outletID != nil {
|
||||
query = query.Where("outlet_id = ?", *outletID)
|
||||
} else {
|
||||
query = query.Where("outlet_id IS NULL")
|
||||
}
|
||||
|
||||
err := query.Preload("ChartOfAccountType").Preload("Parent").Find(&chartOfAccounts).Error
|
||||
return chartOfAccounts, err
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ChartOfAccountTypeRepository interface {
|
||||
Create(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error
|
||||
GetByID(ctx context.Context, id uuid.UUID) (*entities.ChartOfAccountType, error)
|
||||
GetByCode(ctx context.Context, code string) (*entities.ChartOfAccountType, error)
|
||||
Update(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error
|
||||
Delete(ctx context.Context, id uuid.UUID) error
|
||||
List(ctx context.Context, filters map[string]interface{}, page, limit int) ([]*entities.ChartOfAccountType, int, error)
|
||||
GetActive(ctx context.Context) ([]*entities.ChartOfAccountType, error)
|
||||
}
|
||||
|
||||
type ChartOfAccountTypeRepositoryImpl struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewChartOfAccountTypeRepositoryImpl(db *gorm.DB) *ChartOfAccountTypeRepositoryImpl {
|
||||
return &ChartOfAccountTypeRepositoryImpl{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountTypeRepositoryImpl) Create(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error {
|
||||
return r.db.WithContext(ctx).Create(chartOfAccountType).Error
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountTypeRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.ChartOfAccountType, error) {
|
||||
var chartOfAccountType entities.ChartOfAccountType
|
||||
err := r.db.WithContext(ctx).First(&chartOfAccountType, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &chartOfAccountType, nil
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountTypeRepositoryImpl) GetByCode(ctx context.Context, code string) (*entities.ChartOfAccountType, error) {
|
||||
var chartOfAccountType entities.ChartOfAccountType
|
||||
err := r.db.WithContext(ctx).First(&chartOfAccountType, "code = ?", code).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &chartOfAccountType, nil
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountTypeRepositoryImpl) Update(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error {
|
||||
return r.db.WithContext(ctx).Save(chartOfAccountType).Error
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountTypeRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.ChartOfAccountType{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountTypeRepositoryImpl) List(ctx context.Context, filters map[string]interface{}, page, limit int) ([]*entities.ChartOfAccountType, int, error) {
|
||||
var chartOfAccountTypes []*entities.ChartOfAccountType
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.ChartOfAccountType{})
|
||||
|
||||
// Apply filters
|
||||
for key, value := range filters {
|
||||
if value != nil {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Count total
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Apply pagination
|
||||
offset := (page - 1) * limit
|
||||
err := query.Offset(offset).Limit(limit).Find(&chartOfAccountTypes).Error
|
||||
return chartOfAccountTypes, int(total), err
|
||||
}
|
||||
|
||||
func (r *ChartOfAccountTypeRepositoryImpl) GetActive(ctx context.Context) ([]*entities.ChartOfAccountType, error) {
|
||||
var chartOfAccountTypes []*entities.ChartOfAccountType
|
||||
err := r.db.WithContext(ctx).Where("is_active = ?", true).Find(&chartOfAccountTypes).Error
|
||||
return chartOfAccountTypes, err
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type PurchaseOrderRepositoryImpl struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewPurchaseOrderRepositoryImpl(db *gorm.DB) *PurchaseOrderRepositoryImpl {
|
||||
return &PurchaseOrderRepositoryImpl{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) Create(ctx context.Context, po *entities.PurchaseOrder) error {
|
||||
return r.db.WithContext(ctx).Create(po).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.PurchaseOrder, error) {
|
||||
var po entities.PurchaseOrder
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Vendor").
|
||||
Preload("Items.Ingredient").
|
||||
Preload("Items.Unit").
|
||||
Preload("Attachments.File").
|
||||
First(&po, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &po, nil
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) GetByIDAndOrganizationID(ctx context.Context, id, organizationID uuid.UUID) (*entities.PurchaseOrder, error) {
|
||||
var po entities.PurchaseOrder
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Vendor").
|
||||
Preload("Items.Ingredient").
|
||||
Preload("Items.Unit").
|
||||
Preload("Attachments.File").
|
||||
Where("id = ? AND organization_id = ?", id, organizationID).
|
||||
First(&po).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &po, nil
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) Update(ctx context.Context, po *entities.PurchaseOrder) error {
|
||||
return r.db.WithContext(ctx).Save(po).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.PurchaseOrder{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) List(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, limit, offset int) ([]*entities.PurchaseOrder, int64, error) {
|
||||
var pos []*entities.PurchaseOrder
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.PurchaseOrder{}).Where("organization_id = ?", organizationID)
|
||||
|
||||
// Apply filters
|
||||
for key, value := range filters {
|
||||
switch key {
|
||||
case "search":
|
||||
if searchStr, ok := value.(string); ok && searchStr != "" {
|
||||
searchPattern := "%" + strings.ToLower(searchStr) + "%"
|
||||
query = query.Where("LOWER(po_number) LIKE ? OR LOWER(reference) LIKE ?", searchPattern, searchPattern)
|
||||
}
|
||||
case "status":
|
||||
if status, ok := value.(string); ok && status != "" {
|
||||
query = query.Where("status = ?", status)
|
||||
}
|
||||
case "vendor_id":
|
||||
if vendorID, ok := value.(uuid.UUID); ok {
|
||||
query = query.Where("vendor_id = ?", vendorID)
|
||||
}
|
||||
case "start_date":
|
||||
if startDate, ok := value.(time.Time); ok {
|
||||
query = query.Where("transaction_date >= ?", startDate)
|
||||
}
|
||||
case "end_date":
|
||||
if endDate, ok := value.(time.Time); ok {
|
||||
query = query.Where("transaction_date <= ?", endDate)
|
||||
}
|
||||
default:
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
err := query.
|
||||
Preload("Vendor").
|
||||
Preload("Items.Ingredient").
|
||||
Preload("Items.Unit").
|
||||
Preload("Attachments.File").
|
||||
Order("created_at DESC").
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Find(&pos).Error
|
||||
return pos, total, err
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) Count(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&entities.PurchaseOrder{}).Where("organization_id = ?", organizationID)
|
||||
|
||||
// Apply filters
|
||||
for key, value := range filters {
|
||||
switch key {
|
||||
case "search":
|
||||
if searchStr, ok := value.(string); ok && searchStr != "" {
|
||||
searchPattern := "%" + strings.ToLower(searchStr) + "%"
|
||||
query = query.Where("LOWER(po_number) LIKE ? OR LOWER(reference) LIKE ?", searchPattern, searchPattern)
|
||||
}
|
||||
case "status":
|
||||
if status, ok := value.(string); ok && status != "" {
|
||||
query = query.Where("status = ?", status)
|
||||
}
|
||||
case "vendor_id":
|
||||
if vendorID, ok := value.(uuid.UUID); ok {
|
||||
query = query.Where("vendor_id = ?", vendorID)
|
||||
}
|
||||
case "start_date":
|
||||
if startDate, ok := value.(time.Time); ok {
|
||||
query = query.Where("transaction_date >= ?", startDate)
|
||||
}
|
||||
case "end_date":
|
||||
if endDate, ok := value.(time.Time); ok {
|
||||
query = query.Where("transaction_date <= ?", endDate)
|
||||
}
|
||||
default:
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
err := query.Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) GetByPONumber(ctx context.Context, poNumber string, organizationID uuid.UUID) (*entities.PurchaseOrder, error) {
|
||||
var po entities.PurchaseOrder
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("po_number = ? AND organization_id = ?", poNumber, organizationID).
|
||||
First(&po).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &po, nil
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) GetByStatus(ctx context.Context, organizationID uuid.UUID, status string) ([]*entities.PurchaseOrder, error) {
|
||||
var pos []*entities.PurchaseOrder
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("organization_id = ? AND status = ?", organizationID, status).
|
||||
Preload("Vendor").
|
||||
Preload("Items.Ingredient").
|
||||
Preload("Items.Unit").
|
||||
Find(&pos).Error
|
||||
return pos, err
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) GetOverdue(ctx context.Context, organizationID uuid.UUID) ([]*entities.PurchaseOrder, error) {
|
||||
var pos []*entities.PurchaseOrder
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("organization_id = ? AND due_date < ? AND status IN (?)", organizationID, time.Now(), []string{"draft", "sent", "approved"}).
|
||||
Preload("Vendor").
|
||||
Preload("Items.Ingredient").
|
||||
Preload("Items.Unit").
|
||||
Find(&pos).Error
|
||||
return pos, err
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) UpdateStatus(ctx context.Context, id uuid.UUID, status string) error {
|
||||
return r.db.WithContext(ctx).
|
||||
Model(&entities.PurchaseOrder{}).
|
||||
Where("id = ?", id).
|
||||
Update("status", status).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) UpdateTotalAmount(ctx context.Context, id uuid.UUID, totalAmount float64) error {
|
||||
return r.db.WithContext(ctx).
|
||||
Model(&entities.PurchaseOrder{}).
|
||||
Where("id = ?", id).
|
||||
Update("total_amount", totalAmount).Error
|
||||
}
|
||||
|
||||
// Purchase Order Items methods
|
||||
func (r *PurchaseOrderRepositoryImpl) CreateItem(ctx context.Context, item *entities.PurchaseOrderItem) error {
|
||||
return r.db.WithContext(ctx).Create(item).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) UpdateItem(ctx context.Context, item *entities.PurchaseOrderItem) error {
|
||||
return r.db.WithContext(ctx).Save(item).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) DeleteItem(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.PurchaseOrderItem{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) DeleteItemsByPurchaseOrderID(ctx context.Context, purchaseOrderID uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.PurchaseOrderItem{}, "purchase_order_id = ?", purchaseOrderID).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) GetItemsByPurchaseOrderID(ctx context.Context, purchaseOrderID uuid.UUID) ([]*entities.PurchaseOrderItem, error) {
|
||||
var items []*entities.PurchaseOrderItem
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Ingredient").
|
||||
Preload("Unit").
|
||||
Where("purchase_order_id = ?", purchaseOrderID).
|
||||
Find(&items).Error
|
||||
return items, err
|
||||
}
|
||||
|
||||
// Purchase Order Attachments methods
|
||||
func (r *PurchaseOrderRepositoryImpl) CreateAttachment(ctx context.Context, attachment *entities.PurchaseOrderAttachment) error {
|
||||
return r.db.WithContext(ctx).Create(attachment).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) DeleteAttachment(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.PurchaseOrderAttachment{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) DeleteAttachmentsByPurchaseOrderID(ctx context.Context, purchaseOrderID uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.PurchaseOrderAttachment{}, "purchase_order_id = ?", purchaseOrderID).Error
|
||||
}
|
||||
|
||||
func (r *PurchaseOrderRepositoryImpl) GetAttachmentsByPurchaseOrderID(ctx context.Context, purchaseOrderID uuid.UUID) ([]*entities.PurchaseOrderAttachment, error) {
|
||||
var attachments []*entities.PurchaseOrderAttachment
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("File").
|
||||
Where("purchase_order_id = ?", purchaseOrderID).
|
||||
Find(&attachments).Error
|
||||
return attachments, err
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type VendorRepositoryImpl struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewVendorRepositoryImpl(db *gorm.DB) *VendorRepositoryImpl {
|
||||
return &VendorRepositoryImpl{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) Create(ctx context.Context, vendor *entities.Vendor) error {
|
||||
return r.db.WithContext(ctx).Create(vendor).Error
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.Vendor, error) {
|
||||
var vendor entities.Vendor
|
||||
err := r.db.WithContext(ctx).First(&vendor, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vendor, nil
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) GetByIDAndOrganizationID(ctx context.Context, id, organizationID uuid.UUID) (*entities.Vendor, error) {
|
||||
var vendor entities.Vendor
|
||||
err := r.db.WithContext(ctx).Where("id = ? AND organization_id = ?", id, organizationID).First(&vendor).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vendor, nil
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) Update(ctx context.Context, vendor *entities.Vendor) error {
|
||||
return r.db.WithContext(ctx).Save(vendor).Error
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.Vendor{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) List(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}, limit, offset int) ([]*entities.Vendor, int64, error) {
|
||||
var vendors []*entities.Vendor
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.Vendor{}).Where("organization_id = ?", organizationID)
|
||||
|
||||
// Apply filters
|
||||
for key, value := range filters {
|
||||
switch key {
|
||||
case "search":
|
||||
if searchStr, ok := value.(string); ok && searchStr != "" {
|
||||
searchPattern := "%" + strings.ToLower(searchStr) + "%"
|
||||
query = query.Where("LOWER(name) LIKE ? OR LOWER(email) LIKE ? OR LOWER(contact_person) LIKE ?",
|
||||
searchPattern, searchPattern, searchPattern)
|
||||
}
|
||||
case "is_active":
|
||||
if isActive, ok := value.(bool); ok {
|
||||
query = query.Where("is_active = ?", isActive)
|
||||
}
|
||||
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(&vendors).Error
|
||||
return vendors, total, err
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) Count(ctx context.Context, organizationID uuid.UUID, filters map[string]interface{}) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&entities.Vendor{}).Where("organization_id = ?", organizationID)
|
||||
|
||||
// Apply filters
|
||||
for key, value := range filters {
|
||||
switch key {
|
||||
case "search":
|
||||
if searchStr, ok := value.(string); ok && searchStr != "" {
|
||||
searchPattern := "%" + strings.ToLower(searchStr) + "%"
|
||||
query = query.Where("LOWER(name) LIKE ? OR LOWER(email) LIKE ? OR LOWER(contact_person) LIKE ?",
|
||||
searchPattern, searchPattern, searchPattern)
|
||||
}
|
||||
case "is_active":
|
||||
if isActive, ok := value.(bool); ok {
|
||||
query = query.Where("is_active = ?", isActive)
|
||||
}
|
||||
default:
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
err := query.Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) GetByEmail(ctx context.Context, email string, organizationID uuid.UUID) (*entities.Vendor, error) {
|
||||
var vendor entities.Vendor
|
||||
err := r.db.WithContext(ctx).Where("email = ? AND organization_id = ?", email, organizationID).First(&vendor).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vendor, nil
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) GetByName(ctx context.Context, name string, organizationID uuid.UUID) (*entities.Vendor, error) {
|
||||
var vendor entities.Vendor
|
||||
err := r.db.WithContext(ctx).Where("name = ? AND organization_id = ?", name, organizationID).First(&vendor).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vendor, nil
|
||||
}
|
||||
|
||||
func (r *VendorRepositoryImpl) GetActiveVendors(ctx context.Context, organizationID uuid.UUID) ([]*entities.Vendor, error) {
|
||||
var vendors []*entities.Vendor
|
||||
err := r.db.WithContext(ctx).Where("organization_id = ? AND is_active = ?", organizationID, true).Find(&vendors).Error
|
||||
return vendors, err
|
||||
}
|
||||
Reference in New Issue
Block a user