Skip to content

Commit

Permalink
[FEAT][#6] add coa service (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacky-htg authored Aug 8, 2023
1 parent 444107c commit 0a6daf4
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 24 deletions.
11 changes: 11 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
PORT=6050

REDIS_ADDRESS=
REDIS_PASSWORD=

POSTGRES_PORT=5432
POSTGRES_HOST=localhost
POSTGRES_USER=postgres
POSTGRES_PASSWORD=pass
POSTGRES_DB=erp_ledger_db

162 changes: 162 additions & 0 deletions internal/domain/coa/repo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package coa

import (
"context"
"database/sql"
"ledger-service/internal/pkg/app"
"ledger-service/pb/ledgers"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

type Repo struct {
db *sql.DB
tx *sql.Tx
pb ledgers.ChartOfAccount
}

func (a *Repo) Create(ctx context.Context) error {
query := `
INSERT INTO chart_of_accounts (company_id, account_type_id, parent_id, code, name, created_by, updated_by)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id, updated_at, created_at
`

stmt, err := a.tx.PrepareContext(ctx, query)
if err != nil {
return status.Errorf(codes.Internal, "Prepare statement create coa: %v", err)
}
defer stmt.Close()

var parentId sql.NullString
if len(a.pb.Parent.Id) > 0 {
parentId.String = a.pb.Parent.Id
parentId.Valid = true
}

a.pb.CreatedBy = ctx.Value(app.Ctx("user_id")).(string)
a.pb.UpdatedBy = ctx.Value(app.Ctx("user_id")).(string)

err = stmt.QueryRowContext(ctx,
a.pb.CompanyId,
a.pb.AccountType.Id,
parentId,
a.pb.Code,
a.pb.Name,
a.pb.CreatedBy,
a.pb.UpdatedBy,
).Scan(&a.pb.Id, &a.pb.UpdatedAt, &a.pb.CreatedAt)

if err != nil {
return status.Errorf(codes.Internal, "QueryRowContext Create Coa: %v", err)
}

return nil
}

func (a *Repo) Update(ctx context.Context) error {
query := `
UPDATE chart_of_accounts SET
account_type_id = $1,
parent_id = $2,
name = $3,
updated_at = timezone('utc', NOW()),
updated_by = $4
WHERE id = $5 AND company_id = $6
RETURNING created_by, created_at, updated_at
`

stmt, err := a.tx.PrepareContext(ctx, query)
if err != nil {
return status.Errorf(codes.Internal, "Prepare statement update coa: %v", err)
}
defer stmt.Close()

var parentId sql.NullString
if len(a.pb.Parent.Id) > 0 {
parentId.String = a.pb.Parent.Id
parentId.Valid = true
}

a.pb.UpdatedBy = ctx.Value(app.Ctx("user_id")).(string)

err = stmt.QueryRowContext(ctx,
a.pb.AccountType.Id,
parentId,
a.pb.Name,
a.pb.UpdatedBy,
a.pb.Id,
ctx.Value(app.Ctx("user_id")).(string),
).Scan(&a.pb.CreatedBy, &a.pb.CreatedAt, &a.pb.UpdatedAt)

if err != nil {
return status.Errorf(codes.Internal, "QueryRowContext Update Coa: %v", err)
}

return nil
}

func (a *Repo) List(ctx context.Context) (*ledgers.ChartOfAccounts, error) {
var output ledgers.ChartOfAccounts
query := `
SELECT
chart_of_accounts.id, account_type_id, account_types.name account_type_name, parent_id, code, chart_of_accounts.name,
created_at, created_by, updated_at, updated_by
FROM chart_of_accounts
JOIN account_types ON chart_of_accounts.account_type_id = account_types.id
WHERE company_id = $1
ORDER BY parent_id, created_at
`

stmt, err := a.tx.PrepareContext(ctx, query)
if err != nil {
return nil, status.Errorf(codes.Internal, "Prepare statement List coa: %v", err)
}
defer stmt.Close()

rows, err := stmt.QueryContext(ctx, ctx.Value(app.Ctx("company_id")).(string))
if err != nil {
return nil, status.Errorf(codes.Internal, "QueryContext List coa: %v", err)
}

defer rows.Close()

for rows.Next() {
var coa ledgers.ChartOfAccount
err = rows.Scan(
&coa.Id, &coa.AccountType.Id, &coa.AccountType.Name, &coa.Parent.Id, &coa.Code, &coa.Name,
&coa.CreatedAt, &coa.CreatedBy, &coa.UpdatedAt, &coa.UpdatedBy,
)

if err != nil {
return nil, status.Errorf(codes.Internal, "Scan List coa: %v", err)
}

output.ChartOfAccount = append(output.ChartOfAccount, &coa)
}

if rows.Err() != nil {
return nil, status.Errorf(codes.Internal, "Rows Err coa: %v", err)
}

return &output, nil
}

func (a *Repo) Delete(ctx context.Context) (bool, error) {
query := `DELETE FROM chart_of_accounts WHERE id = $1 AND company_id = $2`

stmt, err := a.tx.PrepareContext(ctx, query)
if err != nil {
return false, status.Errorf(codes.Internal, "Prepare statement delete coa: %v", err)
}
defer stmt.Close()

_, err = stmt.ExecContext(ctx, a.pb.Id, ctx.Value(app.Ctx("company_id")).(string))

if err != nil {
return false, status.Errorf(codes.Internal, "ExecContext Coa: %v", err)
}

return true, nil
}
65 changes: 65 additions & 0 deletions internal/domain/coa/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package coa

import (
"context"
"database/sql"

"ledger-service/internal/pkg/app"
"ledger-service/pb/ledgers"
)

type Service struct {
Db *sql.DB
ledgers.UnimplementedChartOfAccountServiceServer
}

func (a *Service) Create(ctx context.Context, in *ledgers.ChartOfAccount) (*ledgers.ChartOfAccount, error) {
repo := Repo{db: a.Db, pb: ledgers.ChartOfAccount{
CompanyId: ctx.Value(app.Ctx("company_id")).(string),
AccountType: in.AccountType,
Parent: in.Parent,
Name: in.Name,
}}

err := repo.Create(ctx)
if err != nil {
return nil, err
}

return &repo.pb, nil
}

func (a *Service) Update(ctx context.Context, in *ledgers.ChartOfAccount) (*ledgers.ChartOfAccount, error) {
repo := Repo{db: a.Db, pb: ledgers.ChartOfAccount{
Id: in.Id,
CompanyId: ctx.Value(app.Ctx("company_id")).(string),
AccountType: in.AccountType,
Parent: in.Parent,
Name: in.Name,
}}

err := repo.Update(ctx)
if err != nil {
return nil, err
}

return &repo.pb, nil
}

func (a *Service) List(ctx context.Context, in *ledgers.EmptyMessage) (*ledgers.ChartOfAccounts, error) {
repo := Repo{db: a.Db}
return repo.List(ctx)
}

func (a *Service) Delete(ctx context.Context, in *ledgers.Id) (*ledgers.BoolMessage, error) {
repo := Repo{db: a.Db, pb: ledgers.ChartOfAccount{
Id: in.Id,
}}

isTrue, err := repo.Delete(ctx)
if err != nil {
return nil, err
}

return &ledgers.BoolMessage{IsTrue: isTrue}, nil
}
19 changes: 6 additions & 13 deletions internal/middleware/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,18 @@ func (a Context) context(ctx context.Context) (context.Context, error) {
return ctx, status.Errorf(codes.Unauthenticated, "user_id metadata is not provided")
}

universityId := md["university_id"]
if len(universityId) == 0 {
return ctx, status.Errorf(codes.Unauthenticated, "university_id metadata is not provided")
}

programStudiId := md["program_studi_id"]
if len(programStudiId) == 0 {
return ctx, status.Errorf(codes.Unauthenticated, "program_studi_id metadata is not provided")
companyId := md["company_id"]
if len(companyId) == 0 {
return ctx, status.Errorf(codes.Unauthenticated, "company_id metadata is not provided")
}

ctx = context.WithValue(ctx, app.Ctx("user_id"), userId[0])
ctx = context.WithValue(ctx, app.Ctx("university_id"), universityId[0])
ctx = context.WithValue(ctx, app.Ctx("program_studi_id"), programStudiId[0])
ctx = context.WithValue(ctx, app.Ctx("company_id"), companyId[0])

// Set token to outgoing metadata
mdOutgoing := metadata.New(map[string]string{
"user_id": userId[0],
"university_id": universityId[0],
"program_studi_id": programStudiId[0],
"user_id": userId[0],
"company_id": companyId[0],
})

ctx = metadata.NewOutgoingContext(ctx, mdOutgoing)
Expand Down
11 changes: 6 additions & 5 deletions internal/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import (
"database/sql"
"log"

"google.golang.org/grpc"
"ledger-service/internal/domain/coa"
"ledger-service/pb/ledgers"

"ledger-service/internal/pkg/db/redis"
"google.golang.org/grpc"
)

// GrpcRoute func
func GrpcRoute(grpcServer *grpc.Server, db *sql.DB, log *log.Logger, cache *redis.Cache) {
//quizServer := quizDomain.QuizService{Db: db, Cache: cache}
//quizPb.RegisterQuizzesServer(grpcServer, &quizServer)
func GrpcRoute(grpcServer *grpc.Server, db *sql.DB, log *log.Logger) {
coaServer := coa.Service{Db: db}
ledgers.RegisterChartOfAccountServiceServer(grpcServer, &coaServer)
}
9 changes: 3 additions & 6 deletions server.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package main

import (
"context"
"log"
"net"
"os"
"time"

grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
_ "github.com/lib/pq"
Expand All @@ -14,7 +12,6 @@ import (
"ledger-service/internal/config"
"ledger-service/internal/middleware"
"ledger-service/internal/pkg/db/postgres"
"ledger-service/internal/pkg/db/redis"
"ledger-service/internal/route"
)

Expand Down Expand Up @@ -45,12 +42,12 @@ func main() {
defer db.Close()

// create redis cache connection
cache, err := redis.NewCache(context.Background(), os.Getenv("REDIS_ADDRESS"), os.Getenv("REDIS_PASSWORD"), 24*time.Hour)
/*cache, err := redis.NewCache(context.Background(), os.Getenv("REDIS_ADDRESS"), os.Getenv("REDIS_PASSWORD"), 24*time.Hour)
if err != nil {
log.Fatalf("cannot create redis connection: %v", err)
return
}
log.Print("connecting to redis cache")
log.Print("connecting to redis cache") */

// listen tcp port
lis, err := net.Listen("tcp", ":"+port)
Expand All @@ -71,7 +68,7 @@ func main() {
grpcServer := grpc.NewServer(serverOptions...)

// routing grpc services
route.GrpcRoute(grpcServer, db, log, cache)
route.GrpcRoute(grpcServer, db, log)

if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %s", err)
Expand Down

0 comments on commit 0a6daf4

Please sign in to comment.