@@ -91,86 +91,73 @@ public function store(Request $request)
9191 public function generateRoster (Request $ request )
9292 {
9393 $ request ->validate ([
94- 'squad_id ' => 'required|exists:squads ,id ' ,
94+ 'schedule_type_id ' => 'required|exists:schedule_types ,id ' ,
9595 'month ' => 'required|string ' ,
9696 'start_date ' => 'required|date ' ,
97- 'pattern ' => 'required|array ' ,
97+ 'squad_id ' => 'nullable|exists:squads,id ' ,
98+ 'pattern ' => 'nullable|array ' ,
9899 ]);
99100
100101 $ baseMonth = Carbon::parse ($ request ->month );
101102 $ startDate = Carbon::parse ($ request ->start_date );
102- $ squad = Squad ::find ($ request ->squad_id );
103+ $ type = ScheduleType ::find ($ request ->schedule_type_id );
103104
104- $ reguEmployees = Employee:: where ( ' squad_id ' , $ request-> squad_id )-> get ();
105- $ staffEmployees = Employee:: where ( ' employee_type ' , ' non_regu_jaga ' )-> get () ;
105+ // Use pattern from request or from type model
106+ $ pattern = $ request -> pattern ?: $ type -> pattern ;
106107
107- $ officeShift = Shift::where ('name ' , 'like ' , '%Kantor% ' )->first ();
108- $ pattern = array_values ($ request ->pattern ); // Reset keys
108+ if (empty ($ pattern )) {
109+ return back ()->with ('error ' , "Pola (pattern) tidak ditemukan untuk tipe ini. Silakan atur di Master Tipe Piket. " );
110+ }
111+
112+ $ pattern = array_values ($ pattern );
109113 $ patternCount = count ($ pattern );
110114
111- if ($ reguEmployees ->isEmpty () && $ staffEmployees ->isEmpty ()) {
115+ // Fetch employees
116+ if ($ request ->squad_id ) {
117+ $ employees = Employee::where ('squad_id ' , $ request ->squad_id )->get ();
118+ $ squad = Squad::find ($ request ->squad_id );
119+ $ logTag = "Regu " . $ squad ->name ;
120+ } else {
121+ // If No Squad but for a specific type (e.g. CPNS Ramadan)
122+ $ employees = Employee::whereHas ('user ' ) // Or specific criteria
123+ ->whereDoesntHave ('squad ' )
124+ ->get ();
125+ $ logTag = $ type ->name ;
126+ }
127+
128+ if ($ employees ->isEmpty ()) {
112129 return back ()->with ('error ' , "Tidak ada data pegawai untuk diproses. " );
113130 }
114131
115132 $ upsertData = [];
116- $ deleteConditions = []; // Array of [employee_id, date]
117133 $ now = now ();
118134
119135 DB ::beginTransaction ();
120136 try {
121- $ currentMonth = $ baseMonth ;
122-
123- // 1. Process Regu Jaga
124- foreach ($ reguEmployees as $ employee ) {
125- for ($ day = 1 ; $ day <= $ currentMonth ->daysInMonth ; $ day ++) {
126- $ dateObj = $ currentMonth ->copy ()->day ($ day );
137+ foreach ($ employees as $ employee ) {
138+ // Different offset for each employee could be added here if needed
139+ // For now, we use a simple start_date diff
140+ for ($ day = 1 ; $ day <= $ baseMonth ->daysInMonth ; $ day ++) {
141+ $ dateObj = $ baseMonth ->copy ()->day ($ day );
127142 $ diffDays = $ startDate ->diffInDays ($ dateObj , false );
128143
129144 $ index = ($ diffDays % $ patternCount );
130145 if ($ index < 0 ) $ index += $ patternCount ;
131146
132- $ shiftIdString = $ pattern [$ index ];
147+ $ shiftToken = $ pattern [$ index ];
133148
134- if ($ shiftIdString ) {
135- // Handle multiple shifts in one day (e.g. "P-M" split by hyphen)
136- $ shiftIds = explode ('- ' , $ shiftIdString );
137-
138- foreach ($ shiftIds as $ sId ) {
139- if (empty ($ sId )) continue ;
140-
141- $ upsertData [] = [
142- 'employee_id ' => $ employee ->id ,
143- 'date ' => $ dateObj ->format ('Y-m-d ' ),
144- 'shift_id ' => $ sId ,
145- 'schedule_type_id ' => $ squad ->schedule_type_id ,
146- 'created_at ' => $ now ,
147- 'updated_at ' => $ now
148- ];
149- }
150- } else {
151- $ deleteConditions [] = ['employee_id ' => $ employee ->id , 'date ' => $ dateObj ->format ('Y-m-d ' ), 'schedule_type_id ' => $ squad ->schedule_type_id ];
152- }
153- }
154- }
149+ if ($ shiftToken && $ shiftToken !== 'I ' ) {
150+ // Find shift by ID or Code/Name
151+ $ shift = is_numeric ($ shiftToken )
152+ ? Shift::find ($ shiftToken )
153+ : Shift::where ('name ' , 'like ' , "%( $ shiftToken)% " )->first ();
155154
156- // 2. Process Staff / Pegawai Lainnya (Automated Office Hours)
157- $ staffType = \App \Models \ScheduleType::where ('code ' , 'staff ' )->first ();
158- $ staffTypeId = $ staffType ? $ staffType ->id : null ;
159- $ officeShift = Shift::where ('name ' , 'like ' , '%Dinas Pagi% ' )
160- ->orWhere ('name ' , 'like ' , '%Kantor% ' )
161- ->first ();
162-
163- if ($ officeShift && $ staffTypeId ) {
164- foreach ($ staffEmployees as $ employee ) {
165- for ($ day = 1 ; $ day <= $ currentMonth ->daysInMonth ; $ day ++) {
166- $ dateObj = $ currentMonth ->copy ()->day ($ day );
167- // Office hours apply Mon-Fri
168- if ($ dateObj ->isWeekday ()) {
155+ if ($ shift ) {
169156 $ upsertData [] = [
170157 'employee_id ' => $ employee ->id ,
171158 'date ' => $ dateObj ->format ('Y-m-d ' ),
172- 'shift_id ' => $ officeShift ->id ,
173- 'schedule_type_id ' => $ staffTypeId ,
159+ 'shift_id ' => $ shift ->id ,
160+ 'schedule_type_id ' => $ type -> id ,
174161 'created_at ' => $ now ,
175162 'updated_at ' => $ now
176163 ];
@@ -179,18 +166,6 @@ public function generateRoster(Request $request)
179166 }
180167 }
181168
182- // Perform Bulk Deletions if any
183- if (!empty ($ deleteConditions )) {
184- $ empIds = array_unique (array_column ($ deleteConditions , 'employee_id ' ));
185- // Use the type id from the first condition or assume they are grouped if needed
186- Schedule::whereIn ('employee_id ' , $ empIds )
187- ->whereMonth ('date ' , $ currentMonth ->month )
188- ->whereYear ('date ' , $ currentMonth ->year )
189- ->whereNotIn ('date ' , array_column ($ upsertData , 'date ' )) // Only delete if not being updated
190- ->delete ();
191- }
192-
193- // Perform Bulk Upsert in chunks
194169 if (!empty ($ upsertData )) {
195170 $ chunks = array_chunk ($ upsertData , 500 );
196171 foreach ($ chunks as $ chunk ) {
@@ -208,10 +183,10 @@ public function generateRoster(Request $request)
208183 'user_id ' => Auth::id (),
209184 'activity ' => 'generate_roster ' ,
210185 'ip_address ' => $ request ->ip (),
211- 'details ' => Auth::user ()->name . " men-generate roster otomatis untuk Regu $ squad -> name dan Staf pada bulan " . $ baseMonth ->translatedFormat ('F Y ' )
186+ 'details ' => Auth::user ()->name . " men-generate roster otomatis untuk $ logTag pada bulan " . $ baseMonth ->translatedFormat ('F Y ' )
212187 ]);
213188
214- return back ()->with ('success ' , "Roster berhasil di-generate secara instan . " );
189+ return back ()->with ('success ' , "Roster berhasil di-generate secara otomatis . " );
215190 }
216191
217192 public function reset (Request $ request )
0 commit comments