diff --git a/internal/database/migrations/20260127114036_change_type_data_column_id_daily_checklist.down.sql b/internal/database/migrations/20260127114036_change_type_data_column_id_daily_checklist.down.sql new file mode 100644 index 00000000..ee02950a --- /dev/null +++ b/internal/database/migrations/20260127114036_change_type_data_column_id_daily_checklist.down.sql @@ -0,0 +1,56 @@ +BEGIN; + +DO $$ +DECLARE + t text; + seq_name text; +BEGIN + FOREACH t IN ARRAY ARRAY[ + 'daily_checklist_activity_task_assignments', + 'daily_checklist_activity_tasks', + 'daily_checklist_phases', + 'daily_checklist_tasks', + 'daily_checklists', + 'employee_kandangs', + 'employees', + 'phase_activities', + 'phases' + ] + LOOP + -- Sequence name convention + seq_name := format('public.%I_id_seq', t); + + -- 1) Drop default nextval (bigserial behavior) + EXECUTE format( + 'ALTER TABLE public.%I ALTER COLUMN id DROP DEFAULT', + t + ); + + -- 2) Add IDENTITY back (BY DEFAULT is safer for rollback) + EXECUTE format( + 'ALTER TABLE public.%I ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY', + t + ); + + -- 3) Detach & optionally drop sequence (safe) + IF EXISTS ( + SELECT 1 FROM pg_class + WHERE relkind = 'S' + AND relname = t || '_id_seq' + ) THEN + EXECUTE format( + 'ALTER SEQUENCE %s OWNED BY NONE', + seq_name + ); + + -- Optional: drop sequence (comment if you want to keep it) + EXECUTE format( + 'DROP SEQUENCE IF EXISTS %s', + seq_name + ); + END IF; + + END LOOP; +END $$; + +COMMIT; diff --git a/internal/database/migrations/20260127114036_change_type_data_column_id_daily_checklist.up.sql b/internal/database/migrations/20260127114036_change_type_data_column_id_daily_checklist.up.sql new file mode 100644 index 00000000..3c1913cb --- /dev/null +++ b/internal/database/migrations/20260127114036_change_type_data_column_id_daily_checklist.up.sql @@ -0,0 +1,59 @@ +BEGIN; + +DO $$ +DECLARE + t text; + seq_name text; + max_id bigint; +BEGIN + FOREACH t IN ARRAY ARRAY[ + 'daily_checklist_activity_task_assignments', + 'daily_checklist_activity_tasks', + 'daily_checklist_phases', + 'daily_checklist_tasks', + 'daily_checklists', + 'employee_kandangs', + 'employees', + 'phase_activities', + 'phases' + ] + LOOP + -- Sequence name convention: public._id_seq + seq_name := format('public.%I_id_seq', t); + + -- Drop IDENTITY only if the column is identity (safe to re-run) + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = t + AND column_name = 'id' + AND is_identity = 'YES' + ) THEN + EXECUTE format('ALTER TABLE public.%I ALTER COLUMN id DROP IDENTITY', t); + END IF; + + -- Ensure sequence exists + EXECUTE format('CREATE SEQUENCE IF NOT EXISTS %s', seq_name); + + -- Set default like bigserial + EXECUTE format( + 'ALTER TABLE public.%I ALTER COLUMN id SET DEFAULT nextval(''%s'')', + t, seq_name + ); + + -- Own the sequence by the column + EXECUTE format( + 'ALTER SEQUENCE %s OWNED BY public.%I.id', + seq_name, t + ); + + -- Sync sequence to MAX(id) + 1 to avoid duplicate key + EXECUTE format('SELECT COALESCE(MAX(id), 0) FROM public.%I', t) INTO max_id; + + EXECUTE format('SELECT setval(''%s'', $1, false)', seq_name) + USING (max_id + 1); + END LOOP; +END $$; + +COMMIT; diff --git a/internal/entities/stock_transfer_delivery.go b/internal/entities/stock_transfer_delivery.go index 0eeccc04..f7ca8a30 100644 --- a/internal/entities/stock_transfer_delivery.go +++ b/internal/entities/stock_transfer_delivery.go @@ -6,7 +6,7 @@ import "time" type StockTransferDelivery struct { Id uint64 `gorm:"primaryKey;autoIncrement"` StockTransferId uint64 - SupplierId uint64 + SupplierId *uint64 VehiclePlate string DriverName string DocumentNumber string diff --git a/internal/modules/closings/repositories/closing.repository.go b/internal/modules/closings/repositories/closing.repository.go index f479306c..04391332 100644 --- a/internal/modules/closings/repositories/closing.repository.go +++ b/internal/modules/closings/repositories/closing.repository.go @@ -355,9 +355,10 @@ func (r *ClosingRepositoryImpl) SumMarketingWeightAndQtyByProjectFlockKandangIDs Joins("JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id"). Joins("JOIN products prod ON prod.id = pw.product_id"). Joins("JOIN flags f ON f.flagable_id = prod.id AND f.flagable_type = ?", "products"). + Joins("JOIN marketing_delivery_products mdp ON mdp.marketing_product_id = mp.id"). Where("pw.project_flock_kandang_id IN ?", projectFlockKandangIDs). Where("f.name IN ?", flagNames). - Select("COALESCE(SUM(mp.total_weight), 0) AS total_weight, COALESCE(SUM(mp.qty), 0) AS total_qty, COALESCE(SUM(mp.total_price), 0) AS total_price"). + Select("COALESCE(SUM(mdp.total_weight), 0) AS total_weight, COALESCE(SUM(mdp.usage_qty), 0) AS total_qty, COALESCE(SUM(mdp.total_price), 0) AS total_price"). Scan(&agg).Error if err != nil { return 0, 0, 0, err @@ -797,7 +798,7 @@ func (r *ClosingRepositoryImpl) detailQuery( ) *gorm.DB { db := r.withCtx(ctx). Table(table). - Joins("JOIN product_warehouses pw ON "+pwJoinCond). + Joins("JOIN product_warehouses pw ON " + pwJoinCond). Joins("JOIN products p ON p.id = pw.product_id") db = applyJoins(db, joins...) @@ -1034,7 +1035,7 @@ func (r *ClosingRepositoryImpl) fetchStockLogs(ctx context.Context, kandangID ui COALESCE(sl.increase,0) AS increase, COALESCE(sl.decrease,0) AS decrease, COALESCE(p.product_price,0) AS price, - `+movementSelect+` + ` + movementSelect + ` `). Joins("JOIN product_warehouses pw ON pw.id = sl.product_warehouse_id"). Joins("JOIN products p ON p.id = pw.product_id"). diff --git a/internal/modules/closings/services/closing.service.go b/internal/modules/closings/services/closing.service.go index eebb531d..78453226 100644 --- a/internal/modules/closings/services/closing.service.go +++ b/internal/modules/closings/services/closing.service.go @@ -162,12 +162,7 @@ func (s closingService) GetProjectFlockByID(c *fiber.Ctx, id uint) (*entity.Proj func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) { - projectFlock, err := s.ProjectFlockRepo.GetByID(c.Context(), projectFlockID, nil) - if err != nil { - return nil, err - } - - realisasi, err := s.MarketingDeliveryProductRepo.GetClosingPenjualan(c.Context(), projectFlockID, projectFlockKandangID, projectFlock.Category) + realisasi, err := s.MarketingDeliveryProductRepo.GetClosingPenjualan(c.Context(), projectFlockID, projectFlockKandangID) if err != nil { return nil, err } diff --git a/internal/modules/closings/services/closingKeuangan.service.go b/internal/modules/closings/services/closingKeuangan.service.go index 85aa5f1c..ca76c67e 100644 --- a/internal/modules/closings/services/closingKeuangan.service.go +++ b/internal/modules/closings/services/closingKeuangan.service.go @@ -270,9 +270,9 @@ func (s closingKeuanganService) calculateProductionData(c *fiber.Ctx, projectFlo var deliveryProducts []entity.MarketingDeliveryProduct if projectFlockKandangID != nil { - deliveryProducts, err = s.MarketingDeliveryProductRepo.GetClosingPenjualan(c.Context(), projectFlock.Id, projectFlockKandangID, projectFlock.Category) + deliveryProducts, err = s.MarketingDeliveryProductRepo.GetClosingPenjualanByCategory(c.Context(), projectFlock.Id, projectFlockKandangID, projectFlock.Category) } else { - deliveryProducts, err = s.MarketingDeliveryProductRepo.GetClosingPenjualan(c.Context(), projectFlock.Id, nil, projectFlock.Category) + deliveryProducts, err = s.MarketingDeliveryProductRepo.GetClosingPenjualanByCategory(c.Context(), projectFlock.Id, nil, projectFlock.Category) } if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil data penjualan") diff --git a/internal/modules/daily-checklists/validations/daily-checklist.validation.go b/internal/modules/daily-checklists/validations/daily-checklist.validation.go index 9157c4e2..353aeaa5 100644 --- a/internal/modules/daily-checklists/validations/daily-checklist.validation.go +++ b/internal/modules/daily-checklists/validations/daily-checklist.validation.go @@ -29,7 +29,7 @@ type Query struct { } type AssignPhases struct { - PhaseIDs string `json:"phase_ids" validate:"required"` + PhaseIDs string `json:"phase_ids" validate:"omitempty"` } type AssignTask struct { diff --git a/internal/modules/inventory/transfers/dto/transfer.dto.go b/internal/modules/inventory/transfers/dto/transfer.dto.go index 73b1a66c..1d29c48d 100644 --- a/internal/modules/inventory/transfers/dto/transfer.dto.go +++ b/internal/modules/inventory/transfers/dto/transfer.dto.go @@ -9,12 +9,12 @@ import ( ) type TransferRelationDTO struct { - Id uint64 `json:"id"` - MovementNumber string `json:"movement_number"` - TransferReason string `json:"transfer_reason"` - TransferDate string `json:"transfer_date"` - SourceWarehouse *warehouseDTO.WarehouseRelationDTO `json:"source_warehouse,omitempty"` - DestinationWarehouse *warehouseDTO.WarehouseRelationDTO `json:"destination_warehouse,omitempty"` + Id uint64 `json:"id"` + MovementNumber string `json:"movement_number"` + TransferReason string `json:"transfer_reason"` + TransferDate string `json:"transfer_date"` + SourceWarehouse *warehouseDTO.WarehouseRelationDTO `json:"source_warehouse,omitempty"` + DestinationWarehouse *warehouseDTO.WarehouseRelationDTO `json:"destination_warehouse,omitempty"` } type ProductSimpleDTO struct { @@ -51,16 +51,16 @@ type TransferDetailDTO struct { } type TransferDetailItemDTO struct { - Id uint64 `json:"id"` - Product ProductSimpleDTO `json:"product"` - Quantity float64 `json:"quantity"` - TransportPerItem *float64 `json:"transport_per_item,omitempty"` // Biaya ekspedisi per item - ExpeditionVendor *SupplierSimpleDTO `json:"expedition_vendor,omitempty"` // Vendor ekspedisi + Id uint64 `json:"id"` + Product ProductSimpleDTO `json:"product"` + Quantity float64 `json:"quantity"` + TransportPerItem *float64 `json:"transport_per_item,omitempty"` // Biaya ekspedisi per item + ExpeditionVendor *SupplierSimpleDTO `json:"expedition_vendor,omitempty"` // Vendor ekspedisi } type TransferDeliveryDTO struct { Id uint64 `json:"id"` - Supplier SupplierSimpleDTO `json:"supplier"` + Supplier *SupplierSimpleDTO `json:"supplier,omitempty"` VehiclePlate string `json:"vehicle_plate"` DriverName string `json:"driver_name"` DocumentNumber string `json:"document_number"` @@ -115,7 +115,6 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO { Quantity: d.UsageQty + d.PendingQty, // Total actual quantity allocated } - if d.ExpenseNonstock != nil { priceCopy := d.ExpenseNonstock.Price detailDTO.TransportPerItem = &priceCopy @@ -155,12 +154,17 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO { } } - deliveries = append(deliveries, TransferDeliveryDTO{ - Id: del.Id, - Supplier: SupplierSimpleDTO{ + var supplier *SupplierSimpleDTO + if del.Supplier != nil { + supplier = &SupplierSimpleDTO{ Id: del.Supplier.Id, Name: del.Supplier.Name, - }, + } + } + + deliveries = append(deliveries, TransferDeliveryDTO{ + Id: del.Id, + Supplier: supplier, VehiclePlate: del.VehiclePlate, DriverName: del.DriverName, DocumentNumber: del.DocumentNumber, @@ -201,7 +205,6 @@ func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO { Quantity: d.UsageQty + d.PendingQty, // Total actual quantity allocated } - if d.ExpenseNonstock != nil { priceCopy := d.ExpenseNonstock.Price detailDTO.TransportPerItem = &priceCopy @@ -241,12 +244,17 @@ func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO { } } - deliveries = append(deliveries, TransferDeliveryDTO{ - Id: del.Id, - Supplier: SupplierSimpleDTO{ + var supplier *SupplierSimpleDTO + if del.Supplier != nil { + supplier = &SupplierSimpleDTO{ Id: del.Supplier.Id, Name: del.Supplier.Name, - }, + } + } + + deliveries = append(deliveries, TransferDeliveryDTO{ + Id: del.Id, + Supplier: supplier, VehiclePlate: del.VehiclePlate, DriverName: del.DriverName, DocumentNumber: del.DocumentNumber, diff --git a/internal/modules/inventory/transfers/services/transfer.service.go b/internal/modules/inventory/transfers/services/transfer.service.go index fe5f8f5a..8278ce9f 100644 --- a/internal/modules/inventory/transfers/services/transfer.service.go +++ b/internal/modules/inventory/transfers/services/transfer.service.go @@ -196,6 +196,11 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques } for _, delivery := range req.Deliveries { + // Skip supplier validation if SupplierID is 0 (optional) + if delivery.SupplierID == 0 { + continue + } + supplier, err := s.SupplierRepo.GetByID(c.Context(), uint(delivery.SupplierID), nil) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { @@ -310,9 +315,16 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques var deliveries []*entity.StockTransferDelivery for _, delivery := range req.Deliveries { + supplierId := func() *uint64 { + if delivery.SupplierID > 0 { + id := uint64(delivery.SupplierID) + return &id + } + return nil + }() deliveries = append(deliveries, &entity.StockTransferDelivery{ StockTransferId: entityTransfer.Id, - SupplierId: uint64(delivery.SupplierID), + SupplierId: supplierId, VehiclePlate: delivery.VehiclePlate, DriverName: delivery.DriverName, ShippingCostItem: delivery.DeliveryCostPerItem, @@ -458,6 +470,11 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques if len(req.Deliveries) > 0 { for _, delivery := range req.Deliveries { + // Skip adding to expensePayloads if SupplierID is 0 (optional) + if delivery.SupplierID == 0 { + continue + } + for _, prod := range delivery.Products { detail := detailMap[uint64(prod.ProductID)] if detail == nil { diff --git a/internal/modules/inventory/transfers/validations/transfer.validation.go b/internal/modules/inventory/transfers/validations/transfer.validation.go index 785295e2..e2f357f3 100644 --- a/internal/modules/inventory/transfers/validations/transfer.validation.go +++ b/internal/modules/inventory/transfers/validations/transfer.validation.go @@ -26,7 +26,7 @@ type TransferDelivery struct { DocumentIndex int `json:"document_index" validate:"omitempty,min=-1" default:"-1"` DriverName string `json:"driver_name" validate:"required"` VehiclePlate string `json:"vehicle_plate" validate:"required"` - SupplierID uint `json:"supplier_id" validate:"required"` + SupplierID uint `json:"supplier_id" ` Products []TransferDeliveryProduct `json:"products" validate:"required,dive"` } diff --git a/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go b/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go index bcd788cd..6f638ac6 100644 --- a/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go +++ b/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go @@ -14,7 +14,8 @@ import ( type MarketingDeliveryProductRepository interface { repository.BaseRepository[entity.MarketingDeliveryProduct] GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error) - GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint, category string) ([]entity.MarketingDeliveryProduct, error) + GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) + GetClosingPenjualanByCategory(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint, category string) ([]entity.MarketingDeliveryProduct, error) GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error) GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error) GetAllWithFilters(ctx context.Context, offset, limit int, filters *validation.MarketingQuery) ([]entity.MarketingDeliveryProduct, int64, error) @@ -54,7 +55,45 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetDeliveryProductsByProjectFlo return deliveryProducts, nil } -func (r *MarketingDeliveryProductRepositoryImpl) GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint, category string) ([]entity.MarketingDeliveryProduct, error) { +func (r *MarketingDeliveryProductRepositoryImpl) GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) { + var deliveryProducts []entity.MarketingDeliveryProduct + + db := r.DB().WithContext(ctx). + Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id"). + Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id"). + Joins("JOIN products ON products.id = product_warehouses.product_id"). + Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id"). + Where("project_flock_kandangs.project_flock_id = ?", projectFlockID). + Where("marketing_delivery_products.delivery_date IS NOT NULL"). + Distinct("marketing_delivery_products.*") + + if projectFlockKandangID != nil { + db = db.Where("product_warehouses.project_flock_kandang_id = ?", *projectFlockKandangID) + } + + db = db. + Preload("MarketingProduct"). + Preload("MarketingProduct.ProductWarehouse"). + Preload("MarketingProduct.ProductWarehouse.Product"). + Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory"). + Preload("MarketingProduct.ProductWarehouse.Product.Uom"). + Preload("MarketingProduct.ProductWarehouse.Product.Flags"). + Preload("MarketingProduct.ProductWarehouse.Warehouse"). + Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang"). + Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang"). + Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Chickins"). + Preload("MarketingProduct.Marketing"). + Preload("MarketingProduct.Marketing.Customer"). + Order("marketing_delivery_products.delivery_date DESC") + + if err := db.Find(&deliveryProducts).Error; err != nil { + return nil, err + } + + return deliveryProducts, nil +} + +func (r *MarketingDeliveryProductRepositoryImpl) GetClosingPenjualanByCategory(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint, category string) ([]entity.MarketingDeliveryProduct, error) { var deliveryProducts []entity.MarketingDeliveryProduct db := r.DB().WithContext(ctx). diff --git a/internal/modules/production/transfer_layings/services/transfer_laying.service.go b/internal/modules/production/transfer_layings/services/transfer_laying.service.go index a5d0ba88..3aa4788b 100644 --- a/internal/modules/production/transfer_layings/services/transfer_laying.service.go +++ b/internal/modules/production/transfer_layings/services/transfer_laying.service.go @@ -650,9 +650,9 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) ( repoTx := s.Repository.WithTx(dbTransaction) approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction)) - // Gunakan repo baru untuk transaction scope agar bisa akses method custom sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction) targetRepoTx := repository.NewLayingTransferTargetRepository(dbTransaction) + stockLogRepoTx := rStockLogs.NewStockLogRepository(dbTransaction) for _, approvableID := range approvableIDs { transfer, err := repoTx.GetByID(c.Context(), approvableID, nil) @@ -687,23 +687,28 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) ( return fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil targets transfer") } - // Hitung total quantity dari targets untuk di-consume dari sources totalTargetQty := 0.0 for _, target := range targets { totalTargetQty += target.TotalQty } - // Consume dari laying_transfer_sources (Usable) - akan consume dari ProjectFlockPopulation (Stockable) + totalSourceRequested := 0.0 + for _, source := range sources { + totalSourceRequested += source.RequestedQty + } + for _, source := range sources { if source.ProductWarehouseId == nil { return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Source product warehouse tidak ditemukan untuk transfer %d", approvableID)) } + sourceShare := (source.RequestedQty / totalSourceRequested) * totalTargetQty + consumeResult, err := s.FifoSvc.Consume(c.Context(), commonSvc.StockConsumeRequest{ UsableKey: fifo.UsableKeyTransferToLayingOut, UsableID: source.Id, ProductWarehouseID: *source.ProductWarehouseId, - Quantity: totalTargetQty, + Quantity: sourceShare, AllowPending: false, Tx: dbTransaction, }) @@ -717,6 +722,19 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) ( }, nil); err != nil { return fiber.NewError(fiber.StatusInternalServerError, "Gagal update source usage qty") } + + stockLogDecrease := &entity.StockLog{ + ProductWarehouseId: *source.ProductWarehouseId, + CreatedBy: actorID, + Increase: 0, + Decrease: sourceShare, + LoggableType: string(utils.StockLogTypeTransferLaying), + LoggableId: approvableID, + Notes: fmt.Sprintf("TL #%s", transfer.TransferNumber), + } + if err := stockLogRepoTx.CreateOne(c.Context(), stockLogDecrease, nil); err != nil { + return fiber.NewError(fiber.StatusInternalServerError, "Gagal membuat log stok keluar") + } } for _, target := range targets { @@ -725,7 +743,7 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) ( } note := fmt.Sprintf("Transfer to Laying #%s", transfer.TransferNumber) - replenishResult, err := s.FifoSvc.Replenish(c.Context(), commonSvc.StockReplenishRequest{ + _, err := s.FifoSvc.Replenish(c.Context(), commonSvc.StockReplenishRequest{ StockableKey: fifo.StockableKeyTransferToLayingIn, StockableID: target.Id, ProductWarehouseID: *target.ProductWarehouseId, @@ -738,10 +756,23 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) ( } if err := targetRepoTx.PatchOne(c.Context(), target.Id, map[string]interface{}{ - "total_qty": replenishResult.AddedQuantity, + "total_qty": target.TotalQty, }, nil); err != nil { return fiber.NewError(fiber.StatusInternalServerError, "Gagal update target total qty") } + + stockLogIncrease := &entity.StockLog{ + ProductWarehouseId: *target.ProductWarehouseId, + CreatedBy: actorID, + Increase: target.TotalQty, + Decrease: 0, + LoggableType: string(utils.StockLogTypeTransferLaying), + LoggableId: approvableID, + Notes: fmt.Sprintf("TL #%s", transfer.TransferNumber), + } + if err := stockLogRepoTx.CreateOne(c.Context(), stockLogIncrease, nil); err != nil { + return fiber.NewError(fiber.StatusInternalServerError, "Gagal membuat log stok masuk") + } } } } diff --git a/internal/modules/production/transfer_layings/validations/transfer_laying.validation.go b/internal/modules/production/transfer_layings/validations/transfer_laying.validation.go index 0472ba39..a2fef4a1 100644 --- a/internal/modules/production/transfer_layings/validations/transfer_laying.validation.go +++ b/internal/modules/production/transfer_layings/validations/transfer_laying.validation.go @@ -30,7 +30,7 @@ type Update struct { type Query struct { Page int `query:"page" validate:"omitempty,number,min=1,gt=0"` - Limit int `query:"limit" validate:"omitempty,number,min=1,max=100,gt=0"` + Limit int `query:"limit" validate:"omitempty,number,min=1,gt=0"` Search string `query:"search" validate:"omitempty"` StartDate string `query:"start_date" validate:"omitempty"` EndDate string `query:"end_date" validate:"omitempty"` diff --git a/internal/utils/constant.go b/internal/utils/constant.go index d27b07ef..cb8586ac 100644 --- a/internal/utils/constant.go +++ b/internal/utils/constant.go @@ -109,12 +109,13 @@ const ( type StockLogType string const ( - StockLogTypeAdjustment StockLogType = "ADJUSTMENT" - StockLogTypeTransfer StockLogType = "TRANSFER" - StockLogTypeMarketing StockLogType = "MARKETING" - StockLogTypeChikin StockLogType = "CHICKIN" - StockLogTypePurchase StockLogType = "PURCHASE" - StockLogTypeRecording StockLogType = "RECORDING" + StockLogTypeAdjustment StockLogType = "ADJUSTMENT" + StockLogTypeTransfer StockLogType = "TRANSFER" + StockLogTypeTransferLaying StockLogType = "TRANSFER_LAYING" + StockLogTypeMarketing StockLogType = "MARKETING" + StockLogTypeChikin StockLogType = "CHICKIN" + StockLogTypePurchase StockLogType = "PURCHASE" + StockLogTypeRecording StockLogType = "RECORDING" ) // -------------------------------------------------------------------