feat[BE]: Refactor Chickin create and approvals support chickin growing and chickin laying, and create get one project flock kandang API

This commit is contained in:
aguhh18
2025-11-02 21:06:03 +07:00
parent 219a6a39ed
commit 20f1be2ef8
21 changed files with 1002 additions and 206 deletions
@@ -0,0 +1,353 @@
package dto
import (
"time"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
areaDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto"
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/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"
chickinDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/dto"
projectFlockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/dto"
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
)
type ProjectFlockKandangBaseDTO struct {
Id uint `json:"id"`
}
type ProjectFlockCustomDTO struct {
Id uint `json:"id"`
Period int `json:"period"`
Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"`
Area *areaDTO.AreaBaseDTO `json:"area,omitempty"`
Category string `json:"category"`
Fcr *fcrDTO.FcrBaseDTO `json:"fcr,omitempty"`
Location *locationDTO.LocationBaseDTO `json:"location,omitempty"`
Kandangs []kandangDTO.KandangBaseDTO `json:"kandangs,omitempty"`
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type KandangCustomDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
}
type ProductBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
}
type WarehouseBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
}
type ProductWarehouseDTO struct {
Id uint `json:"id"`
Quantity float64 `json:"quantity"`
Product *ProductBaseDTO `json:"product,omitempty"`
Warehouse *WarehouseBaseDTO `json:"warehouse,omitempty"`
}
type AvailableQtyDTO struct {
ProductWarehouse *ProductWarehouseDTO `json:"product_warehouse,omitempty"`
}
type ProjectFlockKandangListDTO struct {
ProjectFlockKandangBaseDTO
ProjectFlock *ProjectFlockCustomDTO `json:"project_flock,omitempty"`
Kandang *KandangCustomDTO `json:"kandang,omitempty"`
Chickins []chickinDTO.ChickinBaseDTO `json:"chickins,omitempty"`
AvailableQtys []AvailableQtyDTO `json:"available_qtys,omitempty"`
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
CreatedAt time.Time `json:"created_at"`
Approval *approvalDTO.ApprovalBaseDTO `json:"approval,omitempty"`
}
type ProjectFlockKandangDetailDTO struct {
ProjectFlockKandangListDTO
}
func ToProjectFlockKandangBaseDTO(e entity.ProjectFlockKandang) ProjectFlockKandangBaseDTO {
return ProjectFlockKandangBaseDTO{
Id: e.Id,
}
}
func toProjectFlockCustomDTO(pf *projectFlockDTO.ProjectFlockListDTO) *ProjectFlockCustomDTO {
if pf == nil {
return nil
}
return &ProjectFlockCustomDTO{
Id: pf.Id,
Period: pf.Period,
Flock: pf.Flock,
Area: pf.Area,
Category: pf.Category,
Fcr: pf.Fcr,
Location: pf.Location,
Kandangs: pf.Kandangs,
CreatedUser: pf.CreatedUser,
CreatedAt: pf.CreatedAt,
UpdatedAt: pf.UpdatedAt,
}
}
func buildAvailableQtys(chickins []entity.ProjectChickin) []AvailableQtyDTO {
if len(chickins) == 0 {
return nil
}
availableQtyMap := make(map[uint]AvailableQtyDTO)
for _, ch := range chickins {
if ch.ProductWarehouse == nil || ch.ProductWarehouse.Quantity <= 0 {
continue
}
if _, exists := availableQtyMap[ch.ProductWarehouseId]; exists {
continue
}
pwDTO := &ProductWarehouseDTO{
Id: ch.ProductWarehouse.Id,
Quantity: ch.ProductWarehouse.Quantity,
}
if ch.ProductWarehouse.Product.Id != 0 {
pwDTO.Product = &ProductBaseDTO{
Id: ch.ProductWarehouse.Product.Id,
Name: ch.ProductWarehouse.Product.Name,
}
}
if ch.ProductWarehouse.Warehouse.Id != 0 {
pwDTO.Warehouse = &WarehouseBaseDTO{
Id: ch.ProductWarehouse.Warehouse.Id,
Name: ch.ProductWarehouse.Warehouse.Name,
Type: ch.ProductWarehouse.Warehouse.Type,
}
}
availableQtyMap[ch.ProductWarehouseId] = AvailableQtyDTO{
ProductWarehouse: pwDTO,
}
}
if len(availableQtyMap) == 0 {
return nil
}
result := make([]AvailableQtyDTO, 0, len(availableQtyMap))
for _, v := range availableQtyMap {
result = append(result, v)
}
return result
}
func buildChickins(chickins []entity.ProjectChickin) []chickinDTO.ChickinBaseDTO {
if len(chickins) == 0 {
return nil
}
result := make([]chickinDTO.ChickinBaseDTO, len(chickins))
for i, ch := range chickins {
result[i] = chickinDTO.ToChickinBaseDTO(ch)
}
return result
}
func defaultProjectFlockKandangLatestApproval(e entity.ProjectFlockKandang) *approvalDTO.ApprovalBaseDTO {
if e.LatestApproval != nil {
result := approvalDTO.ToApprovalDTO(*e.LatestApproval)
return &result
}
return nil
}
func ToProjectFlockKandangListDTO(e entity.ProjectFlockKandang) ProjectFlockKandangListDTO {
var projectFlockSummary *projectFlockDTO.ProjectFlockListDTO
if e.ProjectFlock.Id != 0 {
mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock)
projectFlockSummary = &mapped
}
var kandangSummary *KandangCustomDTO
if e.Kandang.Id != 0 {
kandangSummary = &KandangCustomDTO{
Id: e.Kandang.Id,
Name: e.Kandang.Name,
Status: e.Kandang.Status,
}
}
var createdUser *userDTO.UserBaseDTO
if e.ProjectFlock.CreatedUser.Id != 0 {
mapped := userDTO.ToUserBaseDTO(e.ProjectFlock.CreatedUser)
createdUser = &mapped
} else if e.ProjectFlock.CreatedBy != 0 {
mapped := userDTO.UserBaseDTO{Id: e.ProjectFlock.CreatedBy, IdUser: int64(e.ProjectFlock.CreatedBy)}
createdUser = &mapped
}
return ProjectFlockKandangListDTO{
ProjectFlockKandangBaseDTO: ToProjectFlockKandangBaseDTO(e),
ProjectFlock: toProjectFlockCustomDTO(projectFlockSummary),
Kandang: kandangSummary,
Chickins: buildChickins(e.Chickins),
AvailableQtys: buildAvailableQtys(e.Chickins),
CreatedAt: e.CreatedAt,
CreatedUser: createdUser,
Approval: defaultProjectFlockKandangLatestApproval(e),
}
}
func ToProjectFlockKandangListDTOs(e []entity.ProjectFlockKandang) []ProjectFlockKandangListDTO {
result := make([]ProjectFlockKandangListDTO, len(e))
for i, r := range e {
result[i] = ToProjectFlockKandangListDTO(r)
}
return result
}
func ToProjectFlockKandangDetailDTO(e entity.ProjectFlockKandang) ProjectFlockKandangDetailDTO {
return ProjectFlockKandangDetailDTO{
ProjectFlockKandangListDTO: ToProjectFlockKandangListDTO(e),
}
}
func ToProjectFlockKandangListDTOWithAvailableQty(e entity.ProjectFlockKandang, availableQtysRaw []map[string]interface{}) ProjectFlockKandangListDTO {
var projectFlockSummary *projectFlockDTO.ProjectFlockListDTO
if e.ProjectFlock.Id != 0 {
mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock)
projectFlockSummary = &mapped
}
var kandangSummary *KandangCustomDTO
if e.Kandang.Id != 0 {
kandangSummary = &KandangCustomDTO{
Id: e.Kandang.Id,
Name: e.Kandang.Name,
Status: e.Kandang.Status,
}
}
var createdUser *userDTO.UserBaseDTO
if e.ProjectFlock.CreatedUser.Id != 0 {
mapped := userDTO.ToUserBaseDTO(e.ProjectFlock.CreatedUser)
createdUser = &mapped
} else if e.ProjectFlock.CreatedBy != 0 {
mapped := userDTO.UserBaseDTO{Id: e.ProjectFlock.CreatedBy, IdUser: int64(e.ProjectFlock.CreatedBy)}
createdUser = &mapped
}
// convert available qtys from raw map data
var availableQtys []AvailableQtyDTO
if len(availableQtysRaw) > 0 {
availableQtys = buildAvailableQtysFromRaw(availableQtysRaw)
}
return ProjectFlockKandangListDTO{
ProjectFlockKandangBaseDTO: ToProjectFlockKandangBaseDTO(e),
ProjectFlock: toProjectFlockCustomDTO(projectFlockSummary),
Kandang: kandangSummary,
Chickins: buildChickins(e.Chickins),
AvailableQtys: availableQtys,
CreatedAt: e.CreatedAt,
CreatedUser: createdUser,
Approval: defaultProjectFlockKandangLatestApproval(e),
}
}
func buildAvailableQtysFromRaw(availableQtysRaw []map[string]interface{}) []AvailableQtyDTO {
if len(availableQtysRaw) == 0 {
return nil
}
result := make([]AvailableQtyDTO, len(availableQtysRaw))
for i, v := range availableQtysRaw {
pwData, ok := v["product_warehouse"].(map[string]interface{})
if !ok {
continue
}
pwDTO := buildProductWarehouseFromMap(pwData)
result[i] = AvailableQtyDTO{
ProductWarehouse: pwDTO,
}
}
return result
}
func buildProductWarehouseFromMap(pwData map[string]interface{}) *ProductWarehouseDTO {
if pwData == nil {
return nil
}
dto := &ProductWarehouseDTO{}
if id, ok := pwData["id"].(float64); ok {
dto.Id = uint(id)
} else if id, ok := pwData["id"].(uint); ok {
dto.Id = id
}
if qty, ok := pwData["quantity"].(float64); ok {
dto.Quantity = qty
}
if pData, ok := pwData["product"].(map[string]interface{}); ok {
dto.Product = buildProductFromMap(pData)
}
if wData, ok := pwData["warehouse"].(map[string]interface{}); ok {
dto.Warehouse = buildWarehouseFromMap(wData)
}
return dto
}
func buildProductFromMap(pData map[string]interface{}) *ProductBaseDTO {
if pData == nil {
return nil
}
product := &ProductBaseDTO{}
if id, ok := pData["id"].(float64); ok {
product.Id = uint(id)
} else if id, ok := pData["id"].(uint); ok {
product.Id = id
}
if name, ok := pData["name"].(string); ok {
product.Name = name
}
return product
}
func buildWarehouseFromMap(wData map[string]interface{}) *WarehouseBaseDTO {
if wData == nil {
return nil
}
warehouse := &WarehouseBaseDTO{}
if id, ok := wData["id"].(float64); ok {
warehouse.Id = uint(id)
} else if id, ok := wData["id"].(uint); ok {
warehouse.Id = id
}
if name, ok := wData["name"].(string); ok {
warehouse.Name = name
}
if wType, ok := wData["type"].(string); ok {
warehouse.Type = wType
}
return warehouse
}