FIX[BE]: Fix Delete one on chickin match with BE standard

This commit is contained in:
aguhh18
2025-10-29 14:19:08 +07:00
parent 7f00a5a7a4
commit a390d1d23a
4 changed files with 194 additions and 138 deletions
@@ -77,6 +77,7 @@ func (s chickinService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity
}
offset := (params.Page - 1) * params.Limit
chickins, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
db = s.withRelations(db)
if params.ProjectFlockKandangId != 0 {
@@ -241,143 +242,129 @@ func (s chickinService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint)
}
func (s chickinService) DeleteOne(c *fiber.Ctx, id uint) error {
db := s.Repository.DB()
tx := db.WithContext(c.Context()).Begin()
if tx.Error != nil {
s.Log.Errorf("Failed to begin transaction: %+v", tx.Error)
return tx.Error
}
rollback := func(err error) error {
if rerr := tx.Rollback().Error; rerr != nil {
s.Log.Errorf("Rollback failed: %+v", rerr)
err := s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
chickinRepo := repository.NewChickinRepository(dbTransaction)
projectFlockKandangRepo := s.ProjectflockKandangRepo.WithTx(dbTransaction)
productWarehouseRepo := s.ProductWarehouseRepo.WithTxRepo(dbTransaction)
projectFlockPopulationRepo := s.ProjectflockPopulationRepo.WithTx(dbTransaction)
projectChickinDetailRepo := s.ProjectChickinDetailRepo.WithTxRepo(dbTransaction)
warehouseRepoTx := rWarehouse.NewWarehouseRepository(dbTransaction)
chickin, err := chickinRepo.GetByID(c.Context(), id, nil)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Chickin not found")
}
return err
}
population, err := projectFlockPopulationRepo.GetByProjectFlockKandangID(c.Context(), chickin.ProjectFlockKandangId)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Project flock population not found")
}
return err
}
newReserved := population.ReservedQuantity - chickin.Quantity
if newReserved < 0 {
newReserved = 0
}
err = projectFlockPopulationRepo.PatchOne(c.Context(), population.Id, map[string]any{
"reserved_quantity": newReserved,
}, nil)
if err != nil {
return err
}
restoreFromDetails := func() (bool, error) {
details, err := projectChickinDetailRepo.GetByProjectChickinID(c.Context(), chickin.Id)
if err != nil {
return false, err
}
for _, d := range details {
productWarehouse, err := productWarehouseRepo.GetByID(c.Context(), d.ProductWarehouseId, nil)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
continue
}
return false, err
}
updatedQuantity := productWarehouse.Quantity + d.Quantity
if err := productWarehouseRepo.PatchOne(c.Context(), productWarehouse.Id, map[string]any{"quantity": updatedQuantity}, nil); err != nil {
return false, err
}
}
if err := projectChickinDetailRepo.DeleteMany(c.Context(), func(db *gorm.DB) *gorm.DB {
return db.Where("project_chickin_id = ?", chickin.Id)
}); err != nil {
return false, err
}
return true, nil
}
restored, err := restoreFromDetails()
if err != nil {
return err
}
if !restored {
projectflockkandang, err := projectFlockKandangRepo.GetByID(c.Context(), population.ProjectFlockKandangId)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Project flock kandang not found")
}
return err
}
warehouse, err := warehouseRepoTx.GetByKandangID(c.Context(), projectflockkandang.KandangId)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Warehouse not found for kandang")
}
return err
}
productWarehouse, err := productWarehouseRepo.GetLatestByCategoryCodeAndWarehouseID(c.Context(), "DOC", warehouse.Id)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Product Warehouse not found for the given Project Flock and Warehouse")
}
return err
}
updatedQuantity := productWarehouse.Quantity + chickin.Quantity
if err := productWarehouseRepo.PatchOne(c.Context(), productWarehouse.Id, map[string]any{"quantity": updatedQuantity}, nil); err != nil {
return err
}
}
if err := chickinRepo.DeleteOne(c.Context(), id); err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Chickin not found")
}
return err
}
return nil
})
if err != nil {
if ferr, ok := err.(*fiber.Error); ok {
return ferr
}
return err
}
chickinRepoTx := s.Repository.WithTx(tx)
pfkRepoTx := s.ProjectflockKandangRepo.WithTx(tx)
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(tx)
chickin, err := chickinRepoTx.GetByID(c.Context(), id, nil)
if errors.Is(err, gorm.ErrRecordNotFound) {
return rollback(fiber.NewError(fiber.StatusNotFound, "Chickin not found"))
}
if err != nil {
s.Log.Errorf("Failed get chickin by id: %+v", err)
return rollback(err)
}
var population entity.ProjectFlockPopulation
if err := tx.WithContext(c.Context()).Where("project_flock_kandang_id = ?", chickin.ProjectFlockKandangId).First(&population).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return rollback(fiber.NewError(fiber.StatusNotFound, "Project flock population not found"))
}
s.Log.Errorf("Failed to get project flock population: %+v", err)
return rollback(err)
}
newReserved := population.ReservedQuantity - chickin.Quantity
if newReserved < 0 {
newReserved = 0
}
if err := tx.WithContext(c.Context()).Model(&entity.ProjectFlockPopulation{}).Where("id = ?", population.Id).Updates(map[string]any{"reserved_quantity": newReserved}).Error; err != nil {
s.Log.Errorf("Failed to update project flock population: %+v", err)
return rollback(err)
}
restoreFromDetails := func() (bool, error) {
var details []entity.ProjectChickinDetail
if err := tx.WithContext(c.Context()).Where("project_chickin_id = ?", chickin.Id).Find(&details).Error; err != nil {
return false, err
}
if len(details) == 0 {
return false, nil
}
for _, d := range details {
var pw entity.ProductWarehouse
if err := tx.WithContext(c.Context()).Where("id = ?", d.ProductWarehouseId).First(&pw).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
continue
}
return false, err
}
updatedQuantity := pw.Quantity + d.Quantity
if err := productWarehouseRepoTx.PatchOne(c.Context(), pw.Id, map[string]any{"quantity": updatedQuantity}, nil); err != nil {
return false, err
}
}
if err := tx.WithContext(c.Context()).Where("project_chickin_id = ?", chickin.Id).Delete(&entity.ProjectChickinDetail{}).Error; err != nil {
return false, err
}
return true, nil
}
restored, err := restoreFromDetails()
if err != nil {
s.Log.Errorf("Failed to restore from chickin details: %+v", err)
return rollback(err)
}
if !restored {
projectflockkandang, err := pfkRepoTx.GetByID(c.Context(), population.ProjectFlockKandangId)
if err != nil {
s.Log.Errorf("Failed to get projectflock kandang: %+v", err)
return rollback(err)
}
var warehouse entity.Warehouse
if err := tx.WithContext(c.Context()).Where("kandang_id = ?", projectflockkandang.KandangId).First(&warehouse).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return rollback(fiber.NewError(fiber.StatusNotFound, "Warehouse not found for kandang"))
}
s.Log.Errorf("Failed to get warehouse: %+v", err)
return rollback(err)
}
var productWarehouse entity.ProductWarehouse
err = tx.WithContext(c.Context()).Table("product_warehouses").
Select("product_warehouses.*").
Joins("JOIN products ON products.id = product_warehouses.product_id").
Joins("JOIN product_categories ON product_categories.id = products.product_category_id").
Where("product_categories.code = ? AND product_warehouses.warehouse_id = ?", "DOC", warehouse.Id).
Order("product_warehouses.created_at DESC").
First(&productWarehouse).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return rollback(fiber.NewError(fiber.StatusNotFound, "Product Warehouse not found for the given Project Flock and Warehouse"))
}
s.Log.Errorf("Failed to get product warehouse: %+v", err)
return rollback(err)
}
updatedQuantity := productWarehouse.Quantity + chickin.Quantity
if err := productWarehouseRepoTx.PatchOne(c.Context(), productWarehouse.Id, map[string]any{"quantity": updatedQuantity}, nil); err != nil {
s.Log.Errorf("Failed to update product warehouse quantity: %+v", err)
return rollback(err)
}
}
// delete chickin (single place)
if err := chickinRepoTx.DeleteOne(c.Context(), id); err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return rollback(fiber.NewError(fiber.StatusNotFound, "Chickin not found"))
}
s.Log.Errorf("Failed to delete chickin: %+v", err)
return rollback(err)
}
if err := tx.Commit().Error; err != nil {
s.Log.Errorf("Failed to commit transaction: %+v", err)
return rollback(err)
}
return nil
}
@@ -385,11 +372,8 @@ func (s *chickinService) Approve(c *fiber.Ctx, id uint) error {
// todo: ini contoh akhir jika sudah approved
chickin, err := s.Repository.GetByID(
c.Context(),
id,
nil,
)
chickin, err := s.Repository.GetByID(c.Context(), id, nil)
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Chickin not found")
}