This commit is contained in:
Aditya Siregar 2025-09-12 16:37:16 +07:00
parent 91f51d129e
commit 75ec5274d2
8 changed files with 45 additions and 46 deletions

View File

@ -22,26 +22,24 @@ type UpdateChartOfAccountRequest struct {
} }
type ChartOfAccountResponse struct { type ChartOfAccountResponse struct {
ID uuid.UUID `json:"id"` ID uuid.UUID `json:"id"`
OrganizationID uuid.UUID `json:"organization_id"` OrganizationID uuid.UUID `json:"organization_id"`
OutletID *uuid.UUID `json:"outlet_id"` OutletID *uuid.UUID `json:"outlet_id"`
ChartOfAccountTypeID uuid.UUID `json:"chart_of_account_type_id"` ChartOfAccountTypeID uuid.UUID `json:"chart_of_account_type_id"`
ParentID *uuid.UUID `json:"parent_id"` ParentID *uuid.UUID `json:"parent_id"`
Name string `json:"name"` Name string `json:"name"`
Code string `json:"code"` Code string `json:"code"`
Description *string `json:"description"` Description *string `json:"description"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
IsSystem bool `json:"is_system"` IsSystem bool `json:"is_system"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"` UpdatedAt string `json:"updated_at"`
ChartOfAccountType *ChartOfAccountTypeResponse `json:"chart_of_account_type,omitempty"` ChartOfAccountType *ChartOfAccountTypeResponse `json:"chart_of_account_type,omitempty"`
Parent *ChartOfAccountResponse `json:"parent,omitempty"` Parent *ChartOfAccountResponse `json:"parent,omitempty"`
Children []ChartOfAccountResponse `json:"children,omitempty"` Children []ChartOfAccountResponse `json:"children,omitempty"`
} }
type ListChartOfAccountsRequest struct { type ListChartOfAccountsRequest struct {
OrganizationID *uuid.UUID `form:"organization_id"`
OutletID *uuid.UUID `form:"outlet_id"`
ChartOfAccountTypeID *uuid.UUID `form:"chart_of_account_type_id"` ChartOfAccountTypeID *uuid.UUID `form:"chart_of_account_type_id"`
ParentID *uuid.UUID `form:"parent_id"` ParentID *uuid.UUID `form:"parent_id"`
IsActive *bool `form:"is_active"` IsActive *bool `form:"is_active"`

View File

@ -10,7 +10,7 @@ import (
type ChartOfAccount struct { type ChartOfAccount struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"` ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
OrganizationID uuid.UUID `gorm:"type:uuid;not null;index" json:"organization_id" validate:"required"` OrganizationID uuid.UUID `gorm:"type:uuid;not null;index" json:"organization_id" validate:"required"`
OutletID *uuid.UUID `gorm:"type:uuid;index" json:"outlet_id"` OutletID uuid.UUID `gorm:"type:uuid;index" json:"outlet_id"`
ChartOfAccountTypeID uuid.UUID `gorm:"type:uuid;not null;index" json:"chart_of_account_type_id" validate:"required"` ChartOfAccountTypeID uuid.UUID `gorm:"type:uuid;not null;index" json:"chart_of_account_type_id" validate:"required"`
ParentID *uuid.UUID `gorm:"type:uuid;index" json:"parent_id"` ParentID *uuid.UUID `gorm:"type:uuid;index" json:"parent_id"`
Name string `gorm:"not null;size:255" json:"name" validate:"required,min=1,max=255"` Name string `gorm:"not null;size:255" json:"name" validate:"required,min=1,max=255"`

View File

@ -11,7 +11,7 @@ func ChartOfAccountEntityToResponse(entity *entities.ChartOfAccount) *models.Cha
response := &models.ChartOfAccountResponse{ response := &models.ChartOfAccountResponse{
ID: entity.ID, ID: entity.ID,
OrganizationID: entity.OrganizationID, OrganizationID: entity.OrganizationID,
OutletID: entity.OutletID, OutletID: &entity.OutletID,
ChartOfAccountTypeID: entity.ChartOfAccountTypeID, ChartOfAccountTypeID: entity.ChartOfAccountTypeID,
ParentID: entity.ParentID, ParentID: entity.ParentID,
Name: entity.Name, Name: entity.Name,
@ -44,7 +44,7 @@ func ChartOfAccountEntityToResponse(entity *entities.ChartOfAccount) *models.Cha
func ChartOfAccountCreateRequestToEntity(req *models.CreateChartOfAccountRequest, organizationID uuid.UUID, outletID *uuid.UUID) *entities.ChartOfAccount { func ChartOfAccountCreateRequestToEntity(req *models.CreateChartOfAccountRequest, organizationID uuid.UUID, outletID *uuid.UUID) *entities.ChartOfAccount {
return &entities.ChartOfAccount{ return &entities.ChartOfAccount{
OrganizationID: organizationID, OrganizationID: organizationID,
OutletID: outletID, OutletID: *outletID,
ChartOfAccountTypeID: req.ChartOfAccountTypeID, ChartOfAccountTypeID: req.ChartOfAccountTypeID,
ParentID: req.ParentID, ParentID: req.ParentID,
Name: req.Name, Name: req.Name,

View File

@ -3,6 +3,7 @@ package mappers
import ( import (
"apskel-pos-be/internal/contract" "apskel-pos-be/internal/contract"
"apskel-pos-be/internal/models" "apskel-pos-be/internal/models"
"github.com/google/uuid"
"time" "time"
) )
@ -58,10 +59,10 @@ func ContractToModelUpdateChartOfAccountRequest(req *contract.UpdateChartOfAccou
} }
} }
func ContractToModelListChartOfAccountsRequest(req *contract.ListChartOfAccountsRequest) *models.ListChartOfAccountsRequest { func ContractToModelListChartOfAccountsRequest(req *contract.ListChartOfAccountsRequest, organizationID, outletID uuid.UUID) *models.ListChartOfAccountsRequest {
return &models.ListChartOfAccountsRequest{ return &models.ListChartOfAccountsRequest{
OrganizationID: req.OrganizationID, OrganizationID: organizationID,
OutletID: req.OutletID, OutletID: outletID,
ChartOfAccountTypeID: req.ChartOfAccountTypeID, ChartOfAccountTypeID: req.ChartOfAccountTypeID,
ParentID: req.ParentID, ParentID: req.ParentID,
IsActive: req.IsActive, IsActive: req.IsActive,

View File

@ -42,8 +42,8 @@ type UpdateChartOfAccountRequest struct {
} }
type ListChartOfAccountsRequest struct { type ListChartOfAccountsRequest struct {
OrganizationID *uuid.UUID `form:"organization_id"` OrganizationID uuid.UUID `form:"organization_id"`
OutletID *uuid.UUID `form:"outlet_id"` OutletID uuid.UUID `form:"outlet_id"`
ChartOfAccountTypeID *uuid.UUID `form:"chart_of_account_type_id"` ChartOfAccountTypeID *uuid.UUID `form:"chart_of_account_type_id"`
ParentID *uuid.UUID `form:"parent_id"` ParentID *uuid.UUID `form:"parent_id"`
IsActive *bool `form:"is_active"` IsActive *bool `form:"is_active"`

View File

@ -12,7 +12,6 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
) )
type ChartOfAccountProcessor interface { type ChartOfAccountProcessor interface {
CreateChartOfAccount(ctx context.Context, req *models.CreateChartOfAccountRequest) (*models.ChartOfAccountResponse, error) CreateChartOfAccount(ctx context.Context, req *models.CreateChartOfAccountRequest) (*models.ChartOfAccountResponse, error)
GetChartOfAccountByID(ctx context.Context, id uuid.UUID) (*models.ChartOfAccountResponse, error) GetChartOfAccountByID(ctx context.Context, id uuid.UUID) (*models.ChartOfAccountResponse, error)
@ -91,7 +90,7 @@ func (p *ChartOfAccountProcessorImpl) UpdateChartOfAccount(ctx context.Context,
// Check if new code already exists (if code is being updated) // Check if new code already exists (if code is being updated)
if req.Code != nil && *req.Code != entity.Code { if req.Code != nil && *req.Code != entity.Code {
existing, err := p.chartOfAccountRepo.GetByCode(ctx, entity.OrganizationID, *req.Code, entity.OutletID) existing, err := p.chartOfAccountRepo.GetByCode(ctx, entity.OrganizationID, *req.Code, &entity.OutletID)
if err == nil && existing != nil { if err == nil && existing != nil {
return nil, fmt.Errorf("chart of account with code %s already exists", *req.Code) return nil, fmt.Errorf("chart of account with code %s already exists", *req.Code)
} }
@ -142,19 +141,15 @@ func (p *ChartOfAccountProcessorImpl) DeleteChartOfAccount(ctx context.Context,
} }
func (p *ChartOfAccountProcessorImpl) ListChartOfAccounts(ctx context.Context, req *models.ListChartOfAccountsRequest) ([]models.ChartOfAccountResponse, int, error) { func (p *ChartOfAccountProcessorImpl) ListChartOfAccounts(ctx context.Context, req *models.ListChartOfAccountsRequest) ([]models.ChartOfAccountResponse, int, error) {
// Get organization and outlet from context filterEntity := &entities.ChartOfAccount{
appCtx := appcontext.FromGinContext(ctx) OrganizationID: req.OrganizationID,
organizationID := appCtx.OrganizationID OutletID: req.OutletID,
var outletID *uuid.UUID ParentID: req.ParentID,
if appCtx.OutletID != uuid.Nil {
outletID = &appCtx.OutletID
} }
filterEntity := &entities.ChartOfAccount{ // Apply optional filter for ChartOfAccountTypeID
OrganizationID: organizationID, if req.ChartOfAccountTypeID != nil {
OutletID: outletID, filterEntity.ChartOfAccountTypeID = *req.ChartOfAccountTypeID
ChartOfAccountTypeID: *req.ChartOfAccountTypeID,
ParentID: req.ParentID,
} }
entities, total, err := p.chartOfAccountRepo.List(ctx, filterEntity) entities, total, err := p.chartOfAccountRepo.List(ctx, filterEntity)

View File

@ -63,8 +63,8 @@ func (r *ChartOfAccountRepositoryImpl) List(ctx context.Context, req *entities.C
if req.OrganizationID != uuid.Nil { if req.OrganizationID != uuid.Nil {
query = query.Where("organization_id = ?", req.OrganizationID) query = query.Where("organization_id = ?", req.OrganizationID)
} }
if req.OutletID != nil { if req.OutletID != uuid.Nil {
query = query.Where("outlet_id = ?", *req.OutletID) query = query.Where("outlet_id = ?", req.OutletID)
} }
if req.ChartOfAccountTypeID != uuid.Nil { if req.ChartOfAccountTypeID != uuid.Nil {
query = query.Where("chart_of_account_type_id = ?", req.ChartOfAccountTypeID) query = query.Where("chart_of_account_type_id = ?", req.ChartOfAccountTypeID)

View File

@ -1,6 +1,7 @@
package service package service
import ( import (
"apskel-pos-be/internal/appcontext"
"context" "context"
"apskel-pos-be/internal/contract" "apskel-pos-be/internal/contract"
@ -55,17 +56,21 @@ func (s *ChartOfAccountServiceImpl) DeleteChartOfAccount(ctx context.Context, id
} }
func (s *ChartOfAccountServiceImpl) ListChartOfAccounts(ctx context.Context, req *contract.ListChartOfAccountsRequest) ([]contract.ChartOfAccountResponse, int, error) { func (s *ChartOfAccountServiceImpl) ListChartOfAccounts(ctx context.Context, req *contract.ListChartOfAccountsRequest) ([]contract.ChartOfAccountResponse, int, error) {
modelReq := mappers.ContractToModelListChartOfAccountsRequest(req) appCtx := appcontext.FromGinContext(ctx)
organizationID := appCtx.OrganizationID
outletID := appCtx.OutletID
modelReq := mappers.ContractToModelListChartOfAccountsRequest(req, organizationID, outletID)
modelResp, total, err := s.processor.ListChartOfAccounts(ctx, modelReq) modelResp, total, err := s.processor.ListChartOfAccounts(ctx, modelReq)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
contractResp := make([]contract.ChartOfAccountResponse, len(modelResp)) contractResp := make([]contract.ChartOfAccountResponse, len(modelResp))
for i, resp := range modelResp { for i, resp := range modelResp {
contractResp[i] = *mappers.ModelToContractChartOfAccountResponse(&resp) contractResp[i] = *mappers.ModelToContractChartOfAccountResponse(&resp)
} }
return contractResp, total, nil return contractResp, total, nil
} }
@ -74,12 +79,12 @@ func (s *ChartOfAccountServiceImpl) GetChartOfAccountsByOrganization(ctx context
if err != nil { if err != nil {
return nil, err return nil, err
} }
contractResp := make([]contract.ChartOfAccountResponse, len(modelResp)) contractResp := make([]contract.ChartOfAccountResponse, len(modelResp))
for i, resp := range modelResp { for i, resp := range modelResp {
contractResp[i] = *mappers.ModelToContractChartOfAccountResponse(&resp) contractResp[i] = *mappers.ModelToContractChartOfAccountResponse(&resp)
} }
return contractResp, nil return contractResp, nil
} }
@ -88,11 +93,11 @@ func (s *ChartOfAccountServiceImpl) GetChartOfAccountsByType(ctx context.Context
if err != nil { if err != nil {
return nil, err return nil, err
} }
contractResp := make([]contract.ChartOfAccountResponse, len(modelResp)) contractResp := make([]contract.ChartOfAccountResponse, len(modelResp))
for i, resp := range modelResp { for i, resp := range modelResp {
contractResp[i] = *mappers.ModelToContractChartOfAccountResponse(&resp) contractResp[i] = *mappers.ModelToContractChartOfAccountResponse(&resp)
} }
return contractResp, nil return contractResp, nil
} }