mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 07:15:43 +00:00
Feat[BE#280]:add project budgets to body create API and get one API
This commit is contained in:
@@ -5,10 +5,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ProjectBudget struct {
|
type ProjectBudget struct {
|
||||||
Id uint `gorm:"primaryKey"`
|
Id uint `gorm:"primaryKey"`
|
||||||
Qty float64 `gorm:"type:numeric(15,3);not null"`
|
ProjectFlockId uint `gorm:"not null"`
|
||||||
Price float64 `gorm:"type:numeric(15,3);not null"`
|
NonstockId uint `gorm:"not null"`
|
||||||
CreatedAt time.Time `gorm:"autoCreateTime"`
|
Qty float64 `gorm:"type:numeric(15,3);not null"`
|
||||||
|
Price float64 `gorm:"type:numeric(15,3);not null"`
|
||||||
|
CreatedAt time.Time `gorm:"autoCreateTime"`
|
||||||
|
|
||||||
Nonstock *Nonstock `gorm:"foreignKey:Id;references:Id"`
|
Nonstock *Nonstock `gorm:"foreignKey:Id;references:Id"`
|
||||||
ProjectFlock *ProjectFlock `gorm:"foreignKey:Id;references:Id"`
|
ProjectFlock *ProjectFlock `gorm:"foreignKey:Id;references:Id"`
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type ProjectFlock struct {
|
|||||||
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
||||||
Kandangs []Kandang `gorm:"many2many:project_flock_kandangs;joinTableForeignKey:project_flock_id;joinTableReferences:kandang_id" json:"kandangs,omitempty"`
|
Kandangs []Kandang `gorm:"many2many:project_flock_kandangs;joinTableForeignKey:project_flock_id;joinTableReferences:kandang_id" json:"kandangs,omitempty"`
|
||||||
KandangHistory []ProjectFlockKandang `gorm:"foreignKey:ProjectFlockId;references:Id" json:"-"`
|
KandangHistory []ProjectFlockKandang `gorm:"foreignKey:ProjectFlockId;references:Id" json:"-"`
|
||||||
|
Budgets []ProjectBudget `gorm:"foreignKey:ProjectFlockId;references:Id" json:"-"`
|
||||||
|
|
||||||
LatestApproval *Approval `gorm:"-" json:"-"`
|
LatestApproval *Approval `gorm:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
||||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
||||||
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||||
|
nonstockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/dto"
|
||||||
|
|
||||||
// pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
// pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
||||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||||
@@ -24,15 +25,16 @@ type ProjectFlockRelationDTO struct {
|
|||||||
|
|
||||||
type ProjectFlockListDTO struct {
|
type ProjectFlockListDTO struct {
|
||||||
ProjectFlockRelationDTO
|
ProjectFlockRelationDTO
|
||||||
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
||||||
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
||||||
Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"`
|
Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"`
|
||||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user"`
|
ProjectBudgets []ProjectBudgetDTO `json:"project_budgets,omitempty"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedUser *userDTO.UserRelationDTO `json:"created_user"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KandangWithProjectFlockIdDTO struct {
|
type KandangWithProjectFlockIdDTO struct {
|
||||||
@@ -51,6 +53,13 @@ type KandangPeriodSummaryDTO struct {
|
|||||||
Period int `json:"period"`
|
Period int `json:"period"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProjectBudgetDTO struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Qty float64 `json:"qty"`
|
||||||
|
Price float64 `json:"price"`
|
||||||
|
Nonstock *nonstockDTO.NonstockRelationDTO `json:"nonstock,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectFlockListDTO {
|
func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectFlockListDTO {
|
||||||
var createdUser *userDTO.UserRelationDTO
|
var createdUser *userDTO.UserRelationDTO
|
||||||
if e.CreatedUser.Id != 0 {
|
if e.CreatedUser.Id != 0 {
|
||||||
@@ -110,6 +119,7 @@ func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectF
|
|||||||
ProjectFlockRelationDTO: createProjectFlockRelationDTO(e, period),
|
ProjectFlockRelationDTO: createProjectFlockRelationDTO(e, period),
|
||||||
Area: areaSummary,
|
Area: areaSummary,
|
||||||
Kandangs: kandangSummaries,
|
Kandangs: kandangSummaries,
|
||||||
|
ProjectBudgets: ToProjectBudgetDTOs(e.Budgets),
|
||||||
Category: e.Category,
|
Category: e.Category,
|
||||||
Fcr: fcrSummary,
|
Fcr: fcrSummary,
|
||||||
Location: locationSummary,
|
Location: locationSummary,
|
||||||
@@ -184,3 +194,26 @@ func createProjectFlockRelationDTO(e entity.ProjectFlock, period int) ProjectFlo
|
|||||||
FlockName: e.FlockName,
|
FlockName: e.FlockName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToProjectBudgetDTO(e entity.ProjectBudget) ProjectBudgetDTO {
|
||||||
|
var nonstockRef *nonstockDTO.NonstockRelationDTO
|
||||||
|
if e.Nonstock != nil && e.Nonstock.Id != 0 {
|
||||||
|
mapped := nonstockDTO.ToNonstockRelationDTO(*e.Nonstock)
|
||||||
|
nonstockRef = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProjectBudgetDTO{
|
||||||
|
Id: e.Id,
|
||||||
|
Qty: e.Qty,
|
||||||
|
Price: e.Price,
|
||||||
|
Nonstock: nonstockRef,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToProjectBudgetDTOs(e []entity.ProjectBudget) []ProjectBudgetDTO {
|
||||||
|
result := make([]ProjectBudgetDTO, len(e))
|
||||||
|
for i, r := range e {
|
||||||
|
result[i] = ToProjectBudgetDTO(r)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||||
rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
||||||
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
||||||
|
rProjectBudget "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
rProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
rProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
|
|
||||||
sProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services"
|
sProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services"
|
||||||
@@ -31,6 +32,7 @@ func (ProjectflockModule) RegisterRoutes(router fiber.Router, db *gorm.DB, valid
|
|||||||
projectflockKandangRepo := rProjectflock.NewProjectFlockKandangRepository(db)
|
projectflockKandangRepo := rProjectflock.NewProjectFlockKandangRepository(db)
|
||||||
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
|
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
|
||||||
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
||||||
|
projectBudgetRepo := rProjectBudget.NewProjectBudgetRepository(db)
|
||||||
userRepo := rUser.NewUserRepository(db)
|
userRepo := rUser.NewUserRepository(db)
|
||||||
|
|
||||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||||
@@ -39,7 +41,7 @@ func (ProjectflockModule) RegisterRoutes(router fiber.Router, db *gorm.DB, valid
|
|||||||
panic(fmt.Sprintf("failed to register project flock approval workflow: %v", err))
|
panic(fmt.Sprintf("failed to register project flock approval workflow: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
projectflockService := sProjectflock.NewProjectflockService(projectflockRepo, flockRepo, kandangRepo, projectflockKandangRepo, warehouseRepo, productWarehouseRepo, approvalService, validate)
|
projectflockService := sProjectflock.NewProjectflockService(projectflockRepo, flockRepo, kandangRepo, projectflockKandangRepo, warehouseRepo, productWarehouseRepo, projectBudgetRepo, approvalService, validate)
|
||||||
userService := sUser.NewUserService(userRepo, validate)
|
userService := sUser.NewUserService(userRepo, validate)
|
||||||
|
|
||||||
ProjectflockRoutes(router, userService, projectflockService)
|
ProjectflockRoutes(router, userService, projectflockService)
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ func (r *ProjectflockRepositoryImpl) WithDefaultRelations() func(*gorm.DB) *gorm
|
|||||||
Preload("Location").
|
Preload("Location").
|
||||||
Preload("Kandangs").
|
Preload("Kandangs").
|
||||||
Preload("KandangHistory").
|
Preload("KandangHistory").
|
||||||
Preload("KandangHistory.Kandang")
|
Preload("KandangHistory.Kandang").
|
||||||
|
Preload("Budgets").
|
||||||
|
Preload("Budgets.Nonstock")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||||
kandangRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
kandangRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
||||||
warehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
warehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
||||||
|
projectBudgetRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
||||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
|
||||||
@@ -49,6 +50,7 @@ type projectflockService struct {
|
|||||||
KandangRepo kandangRepository.KandangRepository
|
KandangRepo kandangRepository.KandangRepository
|
||||||
WarehouseRepo warehouseRepository.WarehouseRepository
|
WarehouseRepo warehouseRepository.WarehouseRepository
|
||||||
ProductWarehouseRepo productWarehouseRepository.ProductWarehouseRepository
|
ProductWarehouseRepo productWarehouseRepository.ProductWarehouseRepository
|
||||||
|
ProjectBudgetRepo projectBudgetRepository.ProjectBudgetRepository
|
||||||
PivotRepo repository.ProjectFlockKandangRepository
|
PivotRepo repository.ProjectFlockKandangRepository
|
||||||
ApprovalSvc commonSvc.ApprovalService
|
ApprovalSvc commonSvc.ApprovalService
|
||||||
approvalWorkflow approvalutils.ApprovalWorkflowKey
|
approvalWorkflow approvalutils.ApprovalWorkflowKey
|
||||||
@@ -67,8 +69,10 @@ func NewProjectflockService(
|
|||||||
pivotRepo repository.ProjectFlockKandangRepository,
|
pivotRepo repository.ProjectFlockKandangRepository,
|
||||||
warehouseRepo warehouseRepository.WarehouseRepository,
|
warehouseRepo warehouseRepository.WarehouseRepository,
|
||||||
productWarehouseRepo productWarehouseRepository.ProductWarehouseRepository,
|
productWarehouseRepo productWarehouseRepository.ProductWarehouseRepository,
|
||||||
|
projectBudgetRepo projectBudgetRepository.ProjectBudgetRepository,
|
||||||
approvalSvc commonSvc.ApprovalService,
|
approvalSvc commonSvc.ApprovalService,
|
||||||
validate *validator.Validate,
|
validate *validator.Validate,
|
||||||
|
|
||||||
) ProjectflockService {
|
) ProjectflockService {
|
||||||
return &projectflockService{
|
return &projectflockService{
|
||||||
Log: utils.Log,
|
Log: utils.Log,
|
||||||
@@ -289,7 +293,6 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||||
projectRepo := repository.NewProjectflockRepository(dbTransaction)
|
projectRepo := repository.NewProjectflockRepository(dbTransaction)
|
||||||
|
|
||||||
// Generate unique flock name (sequential per base name, starting from 1)
|
|
||||||
generatedName, _, err := s.generateSequentialFlockName(c.Context(), projectRepo, canonicalBase, 1, nil)
|
generatedName, _, err := s.generateSequentialFlockName(c.Context(), projectRepo, canonicalBase, 1, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -300,7 +303,6 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute period per kandang so every kandang maintains its own cycle history.
|
|
||||||
periods, err := projectRepo.GetNextPeriodsForKandangs(c.Context(), kandangIDs)
|
periods, err := projectRepo.GetNextPeriodsForKandangs(c.Context(), kandangIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -309,6 +311,10 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := s.UpsertProjectBudget(c.Context(), dbTransaction, createBody.Id, req.ProjectBudgets); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
action := entity.ApprovalActionCreated
|
action := entity.ApprovalActionCreated
|
||||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||||
_, err = approvalSvcTx.CreateApproval(
|
_, err = approvalSvcTx.CreateApproval(
|
||||||
@@ -1044,3 +1050,35 @@ func (s projectflockService) kandangRepoWithTx(tx *gorm.DB) kandangRepository.Ka
|
|||||||
}
|
}
|
||||||
return kandangRepository.NewKandangRepository(s.Repository.DB())
|
return kandangRepository.NewKandangRepository(s.Repository.DB())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s projectflockService) UpsertProjectBudget(ctx context.Context, dbTransaction *gorm.DB, projectFlockID uint, budgets []validation.ProjectBudget) error {
|
||||||
|
|
||||||
|
if len(budgets) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
budgetRepo := projectBudgetRepository.NewProjectBudgetRepository(dbTransaction)
|
||||||
|
|
||||||
|
if err := budgetRepo.DeleteMany(ctx, func(q *gorm.DB) *gorm.DB {
|
||||||
|
return q.Where("project_flock_id = ?", projectFlockID)
|
||||||
|
}); err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
records := make([]*entity.ProjectBudget, 0, len(budgets))
|
||||||
|
for _, b := range budgets {
|
||||||
|
records = append(records, &entity.ProjectBudget{
|
||||||
|
ProjectFlockId: projectFlockID,
|
||||||
|
NonstockId: b.NonstockId,
|
||||||
|
Price: b.Price,
|
||||||
|
Qty: b.Qty,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := budgetRepo.CreateMany(ctx, records, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
type Create struct {
|
type Create struct {
|
||||||
FlockName string `json:"flock_name" validate:"required_strict"`
|
FlockName string `json:"flock_name" validate:"required_strict"`
|
||||||
AreaId uint `json:"area_id" validate:"required_strict,number,gt=0"`
|
AreaId uint `json:"area_id" validate:"required_strict,number,gt=0"`
|
||||||
Category string `json:"category" validate:"required_strict"`
|
Category string `json:"category" validate:"required_strict"`
|
||||||
FcrId uint `json:"fcr_id" validate:"required_strict,number,gt=0"`
|
FcrId uint `json:"fcr_id" validate:"required_strict,number,gt=0"`
|
||||||
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
||||||
KandangIds []uint `json:"kandang_ids" validate:"required,min=1,dive,gt=0"`
|
KandangIds []uint `json:"kandang_ids" validate:"required,min=1,dive,gt=0"`
|
||||||
|
ProjectBudgets []ProjectBudget `json:"project_budgets" validate:"required,min=1,dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Update struct {
|
type Update struct {
|
||||||
@@ -36,3 +37,9 @@ type Approve struct {
|
|||||||
ApprovableIds []uint `json:"approvable_ids" validate:"required_strict,min=1,dive,gt=0"`
|
ApprovableIds []uint `json:"approvable_ids" validate:"required_strict,min=1,dive,gt=0"`
|
||||||
Notes *string `json:"notes,omitempty" validate:"omitempty,max=500"`
|
Notes *string `json:"notes,omitempty" validate:"omitempty,max=500"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProjectBudget struct {
|
||||||
|
NonstockId uint `json:"nonstock_id" validate:"required_strict,number,gt=0"`
|
||||||
|
Price float64 `json:"price" validate:"required_strict,number,gt=0"`
|
||||||
|
Qty float64 `json:"qty" validate:"required_strict,number,gt=0"`
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user