Feat[BE-261]: creating Entity and repository for each table expenses

This commit is contained in:
aguhh18
2025-11-18 08:18:37 +07:00
parent 5c25c84f7f
commit 1dac74e25b
10 changed files with 193 additions and 39 deletions
+27 -25
View File
@@ -10,44 +10,52 @@ import (
// === DTO Structs ===
type ExpenseBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
Id uint64 `json:"id"`
PoNumber string `json:"po_number"`
ExpenseDate time.Time `json:"expense_date"`
GrandTotal float64 `json:"grand_total"`
}
type ExpenseListDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
CreatedUser *userDTO.UserBaseDTO `json:"created_user"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type ExpenseDetailDTO struct {
ExpenseListDTO
Id uint64 `json:"id"`
ReferenceNumber string `json:"reference_number"`
PoNumber string `json:"po_number"`
Category string `json:"category"`
ExpenseDate time.Time `json:"expense_date"`
GrandTotal float64 `json:"grand_total"`
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// === Mapper Functions ===
func ToExpenseBaseDTO(e entity.Expense) ExpenseBaseDTO {
return ExpenseBaseDTO{
Id: e.Id,
Name: e.Name,
Id: e.Id,
PoNumber: e.PoNumber,
ExpenseDate: e.ExpenseDate,
GrandTotal: e.GrandTotal,
}
}
func ToExpenseListDTO(e entity.Expense) ExpenseListDTO {
var createdUser *userDTO.UserBaseDTO
if e.CreatedUser.Id != 0 {
mapped := userDTO.ToUserBaseDTO(e.CreatedUser)
mapped := userDTO.ToUserBaseDTO(*e.CreatedUser)
createdUser = &mapped
}
return ExpenseListDTO{
Id: e.Id,
Name: e.Name,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedUser: createdUser,
Id: e.Id,
ReferenceNumber: *e.ReferenceNumber,
PoNumber: e.PoNumber,
Category: e.Category,
ExpenseDate: e.ExpenseDate,
GrandTotal: e.GrandTotal,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedUser: createdUser,
}
}
@@ -58,9 +66,3 @@ func ToExpenseListDTOs(e []entity.Expense) []ExpenseListDTO {
}
return result
}
func ToExpenseDetailDTO(e entity.Expense) ExpenseDetailDTO {
return ExpenseDetailDTO{
ExpenseListDTO: ToExpenseListDTO(e),
}
}
@@ -1,13 +1,16 @@
package repository
import (
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"context"
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gorm.io/gorm"
)
type ExpenseRepository interface {
repository.BaseRepository[entity.Expense]
IdExists(ctx context.Context, id uint64) (bool, error)
}
type ExpenseRepositoryImpl struct {
@@ -19,3 +22,7 @@ func NewExpenseRepository(db *gorm.DB) ExpenseRepository {
BaseRepositoryImpl: repository.NewBaseRepository[entity.Expense](db),
}
}
func (r *ExpenseRepositoryImpl) IdExists(ctx context.Context, id uint64) (bool, error) {
return repository.Exists[entity.Expense](ctx, r.DB(), uint(id))
}
@@ -0,0 +1,28 @@
package repository
import (
"context"
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gorm.io/gorm"
)
type ExpenseNonstockRepository interface {
repository.BaseRepository[entity.ExpenseNonstock]
IdExists(ctx context.Context, id uint64) (bool, error)
}
type ExpenseNonstockRepositoryImpl struct {
*repository.BaseRepositoryImpl[entity.ExpenseNonstock]
}
func NewExpenseNonstockRepository(db *gorm.DB) ExpenseNonstockRepository {
return &ExpenseNonstockRepositoryImpl{
BaseRepositoryImpl: repository.NewBaseRepository[entity.ExpenseNonstock](db),
}
}
func (r *ExpenseNonstockRepositoryImpl) IdExists(ctx context.Context, id uint64) (bool, error) {
return repository.Exists[entity.ExpenseNonstock](ctx, r.DB(), uint(id))
}
@@ -0,0 +1,28 @@
package repository
import (
"context"
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gorm.io/gorm"
)
type ExpenseRealizationRepository interface {
repository.BaseRepository[entity.ExpenseRealization]
IdExists(ctx context.Context, id uint64) (bool, error)
}
type ExpenseRealizationRepositoryImpl struct {
*repository.BaseRepositoryImpl[entity.ExpenseRealization]
}
func NewExpenseRealizationRepository(db *gorm.DB) ExpenseRealizationRepository {
return &ExpenseRealizationRepositoryImpl{
BaseRepositoryImpl: repository.NewBaseRepository[entity.ExpenseRealization](db),
}
}
func (r *ExpenseRealizationRepositoryImpl) IdExists(ctx context.Context, id uint64) (bool, error) {
return repository.Exists[entity.ExpenseRealization](ctx, r.DB(), uint(id))
}
@@ -79,8 +79,11 @@ func (s *expenseService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit
return nil, err
}
createdBy := uint64(1)
createBody := &entity.Expense{
Name: req.Name,
PoNumber: req.PoNumber,
Category: req.Category,
CreatedBy: &createdBy,
}
if err := s.Repository.CreateOne(c.Context(), createBody, nil); err != nil {
@@ -88,7 +91,7 @@ func (s *expenseService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit
return nil, err
}
return s.GetOne(c, createBody.Id)
return s.GetOne(c, uint(createBody.Id))
}
func (s expenseService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.Expense, error) {
@@ -98,8 +101,11 @@ func (s expenseService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint)
updateBody := make(map[string]any)
if req.Name != nil {
updateBody["name"] = *req.Name
if req.PoNumber != nil {
updateBody["po_number"] = *req.PoNumber
}
if req.Category != nil {
updateBody["category"] = *req.Category
}
if len(updateBody) == 0 {
@@ -1,11 +1,13 @@
package validation
type Create struct {
Name string `json:"name" validate:"required_strict,min=3"`
PoNumber string `json:"po_number" validate:"required,max=50"`
Category string `json:"category" validate:"required,max=50"`
}
type Update struct {
Name *string `json:"name,omitempty" validate:"omitempty"`
PoNumber *string `json:"po_number,omitempty" validate:"omitempty,max=50"`
Category *string `json:"category,omitempty" validate:"omitempty,max=50"`
}
type Query struct {