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 }