diff --git a/internal/database/seed/seeder.go b/internal/database/seed/seeder.go index 32c3b310..791cfddb 100644 --- a/internal/database/seed/seeder.go +++ b/internal/database/seed/seeder.go @@ -1170,7 +1170,6 @@ func seedChickin(tx *gorm.DB, createdBy uint) error { return err } - // Update/Insert ProjectFlockPopulation var population entity.ProjectFlockPopulation err = tx.Where("project_flock_kandang_id = ?", seed.ProjectFlockKandangId).First(&population).Error if errors.Is(err, gorm.ErrRecordNotFound) { @@ -1198,6 +1197,84 @@ func seedChickin(tx *gorm.DB, createdBy uint) error { return err } } + + var pfk entity.ProjectFlockKandang + if err := tx.Where("id = ?", seed.ProjectFlockKandangId).First(&pfk).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + // no pivot found; skip creating details + continue + } + return err + } + + var warehouse entity.Warehouse + if err := tx.Where("kandang_id = ?", pfk.KandangId).First(&warehouse).Error; err != nil { + // if warehouse not found, cannot create details + if errors.Is(err, gorm.ErrRecordNotFound) { + continue + } + return err + } + + var productWarehouses []entity.ProductWarehouse + err = tx.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"). + Find(&productWarehouses).Error + if err != nil { + return err + } + + // If no product warehouses found, keep existing chickin.Quantity and skip details + if len(productWarehouses) == 0 { + continue + } + + // sum all pw quantities and set chickin.Quantity to that total (mimic CreateOne) + totalQty := 0.0 + for _, pw := range productWarehouses { + totalQty += pw.Quantity + } + + if chickin.Quantity != totalQty { + if err := tx.Model(&entity.ProjectChickin{}).Where("id = ?", chickin.Id).Update("quantity", totalQty).Error; err != nil { + return err + } + chickin.Quantity = totalQty + } + + for _, pw := range productWarehouses { + // ensure detail exists or create it with full pw.Quantity + var detail entity.ProjectChickinDetail + err = tx.Where("project_chickin_id = ? AND product_warehouse_id = ?", chickin.Id, pw.Id).First(&detail).Error + if errors.Is(err, gorm.ErrRecordNotFound) { + detail = entity.ProjectChickinDetail{ + ProjectChickinId: chickin.Id, + ProductWarehouseId: pw.Id, + Quantity: pw.Quantity, + CreatedBy: createdBy, + } + if err := tx.Create(&detail).Error; err != nil { + return err + } + } else if err != nil { + return err + } else { + if detail.Quantity != pw.Quantity { + if err := tx.Model(&entity.ProjectChickinDetail{}).Where("id = ?", detail.Id).Update("quantity", pw.Quantity).Error; err != nil { + return err + } + } + } + + // zero out pw quantity + if err := tx.Model(&entity.ProductWarehouse{}).Where("id = ?", pw.Id).Update("quantity", 0).Error; err != nil { + return err + } + } } return nil diff --git a/internal/modules/production/chickins/services/chickin.service.go b/internal/modules/production/chickins/services/chickin.service.go index de328b46..0df1b6b5 100644 --- a/internal/modules/production/chickins/services/chickin.service.go +++ b/internal/modules/production/chickins/services/chickin.service.go @@ -261,6 +261,7 @@ func (s chickinService) DeleteOne(c *fiber.Ctx, id uint) error { } return err } + chickinRepoTx := s.Repository.WithTx(tx) pfkRepoTx := s.ProjectflockKandangRepo.WithTx(tx) productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(tx) @@ -292,6 +293,86 @@ func (s chickinService) DeleteOne(c *fiber.Ctx, id uint) error { return rollback(err) } + // helper: restore quantities from details; returns (restored bool, error) + 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")) @@ -300,43 +381,6 @@ func (s chickinService) DeleteOne(c *fiber.Ctx, id uint) error { return rollback(err) } - 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) - } - if err := tx.Commit().Error; err != nil { s.Log.Errorf("Failed to commit transaction: %+v", err) return rollback(err)