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 != uuid.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 }