feat[BE-127] add source and target project flock to transfer laying API

This commit is contained in:
aguhh18
2025-11-11 14:32:55 +07:00
parent 6b5d27ae8e
commit 762dfa9fb9
4 changed files with 94 additions and 18 deletions
@@ -2,6 +2,7 @@ package service
import (
"errors"
"time"
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
@@ -106,18 +107,68 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
}
}
createBody := &entity.Marketing{
CustomerId: req.CustomerId,
// parse date
soDate, err := utils.ParseDateString(req.Date)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid date format")
}
err := s.MarketingRepo.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
marketingRepoTx := repository.NewMarketingRepository(dbTransaction)
// generate SO number
soNumber := "SO-" + time.Now().Format("20060102150405")
if err := marketingRepoTx.CreateOne(c.Context(), createBody, nil); err != nil {
var marketing *entity.Marketing
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
// create marketing directly (tanpa create SalesOrders)
marketingRepoTx := repository.NewMarketingRepository(dbTransaction)
marketing = &entity.Marketing{
CustomerId: req.CustomerId,
SoNumber: soNumber,
SoDate: soDate,
SalesPersonId: 1,
Notes: req.Notes,
CreatedBy: 1,
}
if err := marketingRepoTx.CreateOne(c.Context(), marketing, nil); err != nil {
s.Log.Errorf("Failed to create marketing: %+v", err)
return err
}
// Create MarketingProducts and MarketingDeliveryProducts
if len(req.MarketingProducts) > 0 {
for _, product := range req.MarketingProducts {
marketingProduct := &entity.MarketingProduct{
MarketingId: marketing.Id,
ProductWarehouseId: product.ProductWarehouseId,
Qty: product.Qty,
UnitPrice: product.UnitPrice,
AvgWeight: product.AvgWeight,
TotalWeight: product.TotalWeight,
TotalPrice: product.TotalPrice,
}
if err := dbTransaction.Create(marketingProduct).Error; err != nil {
s.Log.Errorf("Failed to create marketing product: %+v", err)
return err
}
// create delivery product with zeroed numeric fields and nil delivery date
marketingDeliveryProduct := &entity.MarketingDeliveryProduct{
MarketingProductId: marketingProduct.Id,
Qty: 0,
UnitPrice: 0,
TotalWeight: 0,
AvgWeight: 0,
TotalPrice: 0,
DeliveryDate: nil,
VehicleNumber: product.VehicleNumber,
}
if err := dbTransaction.Create(marketingDeliveryProduct).Error; err != nil {
s.Log.Errorf("Failed to create marketing delivery product: %+v", err)
return err
}
}
}
return nil
})
if err != nil {
@@ -127,7 +178,16 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create salesOrders")
}
return s.GetOne(c, createBody.Id)
createdMarketing, err := s.MarketingRepo.GetByID(c.Context(), marketing.Id, nil)
if err != nil {
s.Log.Errorf("Failed to fetch created marketing: %+v", err)
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch created marketing")
}
return &entity.SalesOrders{
Id: createdMarketing.Id,
Name: createdMarketing.SoNumber,
}, nil
}
func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.SalesOrders, error) {
@@ -85,7 +85,6 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer
}
}
// Fetch Flock master data for each ProjectFlockKandang
flockMap := make(map[uint]*flockDTO.FlockBaseDTO)
for i := range projectFlockKandangs {
if projectFlockKandangs[i].ProjectFlock.Id != 0 {
@@ -95,7 +94,7 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err)
} else if flock != nil {
// Convert to DTO and store in map with ProjectFlockId as key
flockMap[projectFlockKandangs[i].ProjectFlock.Id] = &flockDTO.FlockBaseDTO{
Id: flock.Id,
Name: flock.Name,
@@ -18,9 +18,9 @@ type TransferLayingBaseDTO struct {
}
type ProjectFlockSummaryDTO struct {
Id uint `json:"id"`
Period int `json:"period"`
Category string `json:"category"`
Id uint `json:"id"`
FlockName string `json:"flock_name"`
Category string `json:"category"`
}
type ProductSummaryDTO struct {
@@ -40,8 +40,13 @@ type ProductWarehouseSummaryDTO struct {
}
type ProjectFlockKandangSummaryDTO struct {
Id uint `json:"id"`
KandangId uint `json:"kandang_id"`
Id uint `json:"id"`
Kandang *KandangSummaryDTO `json:"kandang,omitempty"`
}
type KandangSummaryDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
}
type LayingTransferSourceDTO struct {
@@ -99,9 +104,9 @@ func ToProjectFlockSummaryDTO(pf *entity.ProjectFlock) *ProjectFlockSummaryDTO {
}
return &ProjectFlockSummaryDTO{
Id: pf.Id,
Period: pf.Period,
Category: pf.Category,
Id: pf.Id,
FlockName: pf.FlockName,
Category: pf.Category,
}
}
@@ -110,9 +115,17 @@ func ToProjectFlockKandangSummaryDTO(pfk *entity.ProjectFlockKandang) *ProjectFl
return nil
}
var kandang *KandangSummaryDTO
if pfk.Kandang.Id != 0 {
kandang = &KandangSummaryDTO{
Id: pfk.Kandang.Id,
Name: pfk.Kandang.Name,
}
}
return &ProjectFlockKandangSummaryDTO{
Id: pfk.Id,
KandangId: pfk.KandangId,
Id: pfk.Id,
Kandang: kandang,
}
}
@@ -72,13 +72,17 @@ func NewTransferLayingService(
func (s transferLayingService) withRelations(db *gorm.DB) *gorm.DB {
return db.
Preload("CreatedUser").
Preload("FromProjectFlock").
Preload("ToProjectFlock").
Preload("Sources").
Preload("Sources.SourceProjectFlockKandang").
Preload("Sources.SourceProjectFlockKandang.Kandang").
Preload("Sources.ProductWarehouse").
Preload("Sources.ProductWarehouse.Product").
Preload("Sources.ProductWarehouse.Warehouse").
Preload("Targets").
Preload("Targets.TargetProjectFlockKandang").
Preload("Targets.TargetProjectFlockKandang.Kandang").
Preload("Targets.ProductWarehouse").
Preload("Targets.ProductWarehouse.Product").
Preload("Targets.ProductWarehouse.Warehouse")