mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 23:35:43 +00:00
[FIX/BE-US] add response warehouse and project flock kandang
This commit is contained in:
@@ -82,11 +82,11 @@ type RecordingListDTO struct {
|
||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Warehouse *RecordingWarehouseDTO `json:"warehouse,omitempty"`
|
||||
}
|
||||
|
||||
type RecordingDetailDTO struct {
|
||||
RecordingListDTO
|
||||
Warehouse *RecordingWarehouseDTO `json:"warehouse,omitempty"`
|
||||
ProductCategory string `json:"product_category"`
|
||||
Depletions []RecordingDepletionDTO `json:"depletions"`
|
||||
Stocks []RecordingStockDTO `json:"stocks"`
|
||||
@@ -133,7 +133,6 @@ func ToRecordingDetailDTO(e entity.Recording) RecordingDetailDTO {
|
||||
|
||||
return RecordingDetailDTO{
|
||||
RecordingListDTO: listDTO,
|
||||
Warehouse: recordingWarehouseDTO(e),
|
||||
ProductCategory: recordingProductCategory(e),
|
||||
Depletions: ToRecordingDepletionDTOs(e.Depletions),
|
||||
Stocks: ToRecordingStockDTOs(e.Stocks),
|
||||
@@ -203,6 +202,7 @@ func toRecordingListDTO(e entity.Recording) RecordingListDTO {
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
CreatedUser: createdUser,
|
||||
Warehouse: recordingWarehouseDTO(e),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,22 @@ func (RecordingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate
|
||||
)
|
||||
|
||||
fifoService := commonSvc.NewFifoService(db, stockAllocationRepo, productWarehouseRepo, utils.Log)
|
||||
if err := fifoService.RegisterStockable(fifo.StockableConfig{
|
||||
Key: fifo.StockableKeyRecordingEgg,
|
||||
Table: "recording_eggs",
|
||||
Columns: fifo.StockableColumns{
|
||||
ID: "id",
|
||||
ProductWarehouseID: "product_warehouse_id",
|
||||
TotalQuantity: "total_qty",
|
||||
TotalUsedQuantity: "total_used",
|
||||
CreatedAt: "created_at",
|
||||
},
|
||||
OrderBy: []string{"created_at ASC", "id ASC"},
|
||||
}); err != nil {
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "already registered") {
|
||||
panic(fmt.Sprintf("failed to register recording egg stockable workflow: %v", err))
|
||||
}
|
||||
}
|
||||
if err := fifoService.RegisterUsable(fifo.UsableConfig{
|
||||
Key: fifo.UsableKeyRecordingStock,
|
||||
Table: "recording_stocks",
|
||||
|
||||
@@ -290,8 +290,19 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent
|
||||
s.Log.Errorf("Failed to persist eggs: %+v", err)
|
||||
return err
|
||||
}
|
||||
if s.FifoSvc != nil {
|
||||
if err := s.replenishRecordingEggs(ctx, tx, mappedEggs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, mappedDepletions, nil, mappedEggs)); err != nil {
|
||||
var warehouseDeltas map[uint]float64
|
||||
if s.FifoSvc != nil {
|
||||
warehouseDeltas = buildWarehouseDeltas(nil, mappedDepletions, nil, nil)
|
||||
} else {
|
||||
warehouseDeltas = buildWarehouseDeltas(nil, mappedDepletions, nil, mappedEggs)
|
||||
}
|
||||
if err := s.adjustProductWarehouseQuantities(ctx, tx, warehouseDeltas); err != nil {
|
||||
s.Log.Errorf("Failed to adjust product warehouses: %+v", err)
|
||||
return err
|
||||
}
|
||||
@@ -438,6 +449,16 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
}
|
||||
|
||||
if hasEggChanges {
|
||||
if s.FifoSvc != nil {
|
||||
if err := ensureRecordingEggsUnused(existingEggs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, existingEggs, nil)); err != nil {
|
||||
s.Log.Errorf("Failed to adjust product warehouses for eggs: %+v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Repository.DeleteEggs(tx, recordingEntity.Id); err != nil {
|
||||
s.Log.Errorf("Failed to clear eggs: %+v", err)
|
||||
return err
|
||||
@@ -449,9 +470,15 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, existingEggs, mappedEggs)); err != nil {
|
||||
s.Log.Errorf("Failed to adjust product warehouses for eggs: %+v", err)
|
||||
return err
|
||||
if s.FifoSvc != nil {
|
||||
if err := s.replenishRecordingEggs(ctx, tx, mappedEggs); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, existingEggs, mappedEggs)); err != nil {
|
||||
s.Log.Errorf("Failed to adjust product warehouses for eggs: %+v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,6 +653,11 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
s.Log.Errorf("Failed to list eggs before delete: %+v", err)
|
||||
return err
|
||||
}
|
||||
if s.FifoSvc != nil {
|
||||
if err := ensureRecordingEggsUnused(oldEggs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
oldStocks, err := s.Repository.ListStocks(tx, id)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -802,6 +834,32 @@ func (s *recordingService) adjustProductWarehouseQuantities(ctx context.Context,
|
||||
return s.ProductWarehouseRepo.AdjustQuantities(ctx, deltas, func(*gorm.DB) *gorm.DB { return tx })
|
||||
}
|
||||
|
||||
func (s *recordingService) replenishRecordingEggs(ctx context.Context, tx *gorm.DB, eggs []entity.RecordingEgg) error {
|
||||
if len(eggs) == 0 || s.FifoSvc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, egg := range eggs {
|
||||
if egg.Id == 0 || egg.ProductWarehouseId == 0 || egg.Qty <= 0 {
|
||||
continue
|
||||
}
|
||||
note := fmt.Sprintf("Recording egg #%d", egg.Id)
|
||||
if _, err := s.FifoSvc.Replenish(ctx, commonSvc.StockReplenishRequest{
|
||||
StockableKey: fifo.StockableKeyRecordingEgg,
|
||||
StockableID: egg.Id,
|
||||
ProductWarehouseID: egg.ProductWarehouseId,
|
||||
Quantity: float64(egg.Qty),
|
||||
Note: ¬e,
|
||||
Tx: tx,
|
||||
}); err != nil {
|
||||
s.Log.Errorf("Failed to replenish FIFO stock for recording egg %d: %+v", egg.Id, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type desiredStock struct {
|
||||
Usage float64
|
||||
Pending float64
|
||||
@@ -922,6 +980,14 @@ type eggTotals struct {
|
||||
Weight float64
|
||||
}
|
||||
|
||||
func ensureRecordingEggsUnused(eggs []entity.RecordingEgg) error {
|
||||
for _, egg := range eggs {
|
||||
if egg.TotalUsed > 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Recording egg sudah digunakan sehingga tidak dapat diubah")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stocksMatch(existing []entity.RecordingStock, incoming []validation.Stock) bool {
|
||||
hasPending := false
|
||||
|
||||
Reference in New Issue
Block a user