diff --git a/internal/database/migrations/20251019040246_create_stock_availabilities_table.down.sql b/internal/database/migrations/20251019040246_create_stock_availabilities_table.down.sql deleted file mode 100644 index 1d50d98b..00000000 --- a/internal/database/migrations/20251019040246_create_stock_availabilities_table.down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE IF EXISTS stock_availabilities; \ No newline at end of file diff --git a/internal/database/migrations/20251019040246_create_stock_availabilities_table.up.sql b/internal/database/migrations/20251019040246_create_stock_availabilities_table.up.sql deleted file mode 100644 index bce6f7e6..00000000 --- a/internal/database/migrations/20251019040246_create_stock_availabilities_table.up.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TABLE stock_availabilities ( - id BIGSERIAL PRIMARY KEY, - entity_type VARCHAR(50) NOT NULL, - entity_id BIGINT NOT NULL, - product_id BIGINT, - quantity NUMERIC(15, 3) NOT NULL DEFAULT 0, - reserved_quantity NUMERIC(15, 3) NOT NULL DEFAULT 0, - unit VARCHAR(20), - last_updated TIMESTAMPTZ DEFAULT now(), - created_at TIMESTAMPTZ DEFAULT now(), - deleted_at TIMESTAMPTZ -); - -ALTER TABLE stock_availabilities -ADD CONSTRAINT fk_product_id FOREIGN KEY (product_id) REFERENCES products (id); \ No newline at end of file diff --git a/internal/database/migrations/20251019141014_create_audit_logs_table.down.sql b/internal/database/migrations/20251019141014_create_audit_logs_table.down.sql deleted file mode 100644 index 4cf6b411..00000000 --- a/internal/database/migrations/20251019141014_create_audit_logs_table.down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE IF EXISTS audit_logs; \ No newline at end of file diff --git a/internal/database/migrations/20251019141014_create_audit_logs_table.up.sql b/internal/database/migrations/20251019141014_create_audit_logs_table.up.sql deleted file mode 100644 index 13731dcc..00000000 --- a/internal/database/migrations/20251019141014_create_audit_logs_table.up.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE audit_logs ( - id BIGSERIAL PRIMARY KEY, - table_name VARCHAR(100) NOT NULL, - record_id BIGINT NOT NULL, - action VARCHAR(30) NOT NULL, - before_data JSONB, - after_data JSONB, - changed_by BIGINT, - created_at TIMESTAMPTZ DEFAULT now() -); - -ALTER TABLE audit_logs -ADD CONSTRAINT fk_changed_by FOREIGN KEY (changed_by) REFERENCES users (id); \ No newline at end of file diff --git a/internal/modules/inventory/adjustments/controllers/adjustment.controller.go b/internal/modules/inventory/adjustments/controllers/adjustment.controller.go index dc3df0a9..617a1b5f 100644 --- a/internal/modules/inventory/adjustments/controllers/adjustment.controller.go +++ b/internal/modules/inventory/adjustments/controllers/adjustment.controller.go @@ -49,8 +49,8 @@ func (u *AdjustmentController) AdjustmentHistory(c *fiber.Ctx) error { query := &validation.Query{ Page: c.QueryInt("page", 1), Limit: c.QueryInt("limit", 10), - ProductID: c.QueryInt("product_id", 0), - WarehouseID: c.QueryInt("warehouse_id", 0), + ProductID: uint(c.QueryInt("product_id", 0)), + WarehouseID: uint(c.QueryInt("warehouse_id", 0)), TransactionType: c.Query("transaction_type", ""), } diff --git a/internal/modules/inventory/adjustments/services/adjustment.service.go b/internal/modules/inventory/adjustments/services/adjustment.service.go index 69654b85..7a2d06bc 100644 --- a/internal/modules/inventory/adjustments/services/adjustment.service.go +++ b/internal/modules/inventory/adjustments/services/adjustment.service.go @@ -4,6 +4,8 @@ import ( "errors" "strings" + common "gitlab.com/mbugroup/lti-api.git/internal/common/service" + entity "gitlab.com/mbugroup/lti-api.git/internal/entities" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/adjustments/validations" ProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories" @@ -77,22 +79,11 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e } ctx := c.Context() - isProductExist, err := s.ProductRepo.IdExists(c.Context(), uint(req.ProductID)) - if err != nil { - s.Log.Errorf("Failed to check product existence: %+v", err) - return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product") - } - if !isProductExist { - return nil, fiber.NewError(fiber.StatusNotFound, "Product not found") - } - - isWarehouseExist, err := s.WarehouseRepo.IdExists(c.Context(), uint(req.WarehouseID)) - if err != nil { - s.Log.Errorf("Failed to check warehouse existence: %+v", err) - return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate warehouse") - } - if !isWarehouseExist { - return nil, fiber.NewError(fiber.StatusNotFound, "Warehouse not found") + if err := common.EnsureRelations(c.Context(), + common.RelationCheck{Name: "Product", ID: &req.ProductID, Exists: s.ProductRepo.IdExists}, + common.RelationCheck{Name: "Warehouse", ID: &req.WarehouseID, Exists: s.WarehouseRepo.IdExists}, + ); err != nil { + return nil, err } if req.Quantity <= 0 { @@ -118,6 +109,7 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e Quantity: 0, CreatedBy: 1, // TODO: should Get from auth middleware } + if err := s.ProductWarehouseRepo.CreateOne(ctx, newPW, nil); err != nil { s.Log.Errorf("Failed to create product warehouse: %+v", err) return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create product warehouse") @@ -126,7 +118,6 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e } err = s.StockLogsRepository.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error { - productWarehouse, err := s.ProductWarehouseRepo.GetProductWarehouseByProductAndWarehouseID(ctx, uint(req.ProductID), uint(req.WarehouseID)) if err != nil { s.Log.Errorf("Failed to get product warehouse: %+v", err) @@ -159,14 +150,12 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e s.Log.Errorf("Failed to create stock log: %+v", err) return err } - s.Log.Infof("Stock log created: %+v", newLog.Id) productWarehouse.Quantity = afterQuantity if err := s.ProductWarehouseRepo.WithTx(tx).UpdateOne(ctx, productWarehouse.Id, productWarehouse, nil); err != nil { s.Log.Errorf("Failed to update product warehouse quantity: %+v", err) return err } - s.Log.Infof("Product warehouse quantity updated: %+v", productWarehouse.Id) createdLogId = newLog.Id return nil @@ -184,7 +173,6 @@ func (s *adjustmentService) AdjustmentHistory(c *fiber.Ctx, query *validation.Qu if err := s.Validate.Struct(query); err != nil { return nil, 0, err } - offset := (query.Page - 1) * query.Limit isWarehousesExist, err := s.WarehouseRepo.IdExists(c.Context(), uint(query.WarehouseID)) diff --git a/internal/modules/inventory/adjustments/validations/adjustment.validation.go b/internal/modules/inventory/adjustments/validations/adjustment.validation.go index 7d2385cc..2e7259f2 100644 --- a/internal/modules/inventory/adjustments/validations/adjustment.validation.go +++ b/internal/modules/inventory/adjustments/validations/adjustment.validation.go @@ -11,7 +11,7 @@ type Create struct { type Query struct { Page int `query:"page" validate:"omitempty,min=1"` Limit int `query:"limit" validate:"omitempty,min=1,max=100"` - ProductID int `query:"product_id" validate:"omitempty,min=0"` - WarehouseID int `query:"warehouse_id" validate:"omitempty,min=0"` + ProductID uint `query:"product_id" validate:"omitempty,min=0"` + WarehouseID uint `query:"warehouse_id" validate:"omitempty,min=0"` TransactionType string `query:"transaction_type" validate:"omitempty,oneof=increase decrease"` } diff --git a/internal/modules/production/chickins/services/chickin.service.go b/internal/modules/production/chickins/services/chickin.service.go index f866e96d..64fe1e97 100644 --- a/internal/modules/production/chickins/services/chickin.service.go +++ b/internal/modules/production/chickins/services/chickin.service.go @@ -132,27 +132,33 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit s.Log.Errorf("Failed to get project flock: %+v", err) return nil, fiber.NewError(fiber.StatusNotFound, "Project Flock not found") } - - var productWarehouse entity.ProductWarehouse + var productWarehouses []entity.ProductWarehouse err = s.ProductWarehouseRepo.DB(). WithContext(c.Context()). 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 = ?", projectFlock.ProductCategory.Code, warehouse.Id). Order("created_at DESC"). - First(&productWarehouse).Error + Find(&productWarehouses).Error if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, 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) + s.Log.Errorf("Failed to get product warehouses: %+v", err) return nil, err } - - if productWarehouse.Quantity < 1 { - return nil, fiber.NewError(fiber.StatusBadRequest, "Insufficient product quantity in warehouse") + if len(productWarehouses) == 0 { + return nil, fiber.NewError(fiber.StatusNotFound, "Product Warehouse not found for the given Project Flock and Warehouse") } + // Jumlahkan semua quantity DOC + totalQuantity := 0.0 + for _, pw := range productWarehouses { + totalQuantity += pw.Quantity + } + + if totalQuantity < 1 { + return nil, fiber.NewError(fiber.StatusBadRequest, "Insufficient quantity in Product Warehouses") + } + + // Buat satu chickin dengan total quantity chickinDate, err := utils.ParseDateString(req.ChickInDate) if err != nil { s.Log.Errorf("Failed to parse chickin date: %+v", err) @@ -161,9 +167,9 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit newChickin := &entity.ProjectChickin{ ProjectFlockKandangId: projectflockkandang.ProjectFlockId, ChickInDate: chickinDate, - Quantity: productWarehouse.Quantity, + Quantity: totalQuantity, Note: "", - CreatedBy: 1, //todo: ganti dengan + CreatedBy: 1, //todo: ganti dengan user login } err = s.Repository.CreateOne(c.Context(), newChickin, nil) if err != nil { @@ -171,16 +177,15 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit return nil, err } - updatedQuantity := productWarehouse.Quantity - newChickin.Quantity - if updatedQuantity < 0 { - updatedQuantity = 0 - } - err = s.ProductWarehouseRepo.PatchOne(c.Context(), productWarehouse.Id, map[string]any{ - "quantity": updatedQuantity, - }, nil) - if err != nil { - s.Log.Errorf("Failed to update product warehouse quantity: %+v", err) - return nil, err + // Update semua product warehouse: set quantity jadi 0 + for _, pw := range productWarehouses { + err = s.ProductWarehouseRepo.PatchOne(c.Context(), pw.Id, map[string]any{ + "quantity": 0, + }, nil) + if err != nil { + s.Log.Errorf("Failed to update product warehouse quantity: %+v", err) + return nil, err + } } existingPopulation, err := s.ProjectflockPopulationRepo.GetByProjectFlockKandangID(c.Context(), req.ProjectFlockKandangId)