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/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/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 {