@@ -209,6 +209,206 @@ public void testOtInfoV2Deserialization() {
209209 System .out .println (gson .toJson (option .getOtInfoV2 ()));
210210 }
211211
212+ /**
213+ * Test late_rule field deserialization in getCropCheckinOption response.
214+ */
215+ @ Test
216+ public void testLateRuleDeserialization () {
217+ // Test JSON with late_rule structure based on the issue #3323
218+ String jsonWithLateRule = "{\n " +
219+ " \" grouptype\" : 1,\n " +
220+ " \" groupid\" : 1,\n " +
221+ " \" checkindate\" : [\n " +
222+ " {\n " +
223+ " \" workdays\" : [1, 2, 3, 4, 5],\n " +
224+ " \" checkintime\" : [\n " +
225+ " {\n " +
226+ " \" time_id\" : 1,\n " +
227+ " \" work_sec\" : 32400,\n " +
228+ " \" off_work_sec\" : 64800,\n " +
229+ " \" remind_work_sec\" : 31800,\n " +
230+ " \" remind_off_work_sec\" : 64800,\n " +
231+ " \" rest_begin_time\" : 43200,\n " +
232+ " \" rest_end_time\" : 48600,\n " +
233+ " \" allow_rest\" : true,\n " +
234+ " \" earliest_work_sec\" : 21600,\n " +
235+ " \" latest_work_sec\" : 64740,\n " +
236+ " \" earliest_off_work_sec\" : 32460,\n " +
237+ " \" latest_off_work_sec\" : 107940,\n " +
238+ " \" no_need_checkon\" : false,\n " +
239+ " \" no_need_checkoff\" : false\n " +
240+ " }\n " +
241+ " ],\n " +
242+ " \" noneed_offwork\" : false,\n " +
243+ " \" limit_aheadtime\" : 0,\n " +
244+ " \" flex_on_duty_time\" : 0,\n " +
245+ " \" flex_off_duty_time\" : 0,\n " +
246+ " \" allow_flex\" : false,\n " +
247+ " \" late_rule\" : {\n " +
248+ " \" offwork_after_time\" : 3600,\n " +
249+ " \" onwork_flex_time\" : 3600,\n " +
250+ " \" allow_offwork_after_time\" : true,\n " +
251+ " \" timerules\" : [\n " +
252+ " {\n " +
253+ " \" offwork_after_time\" : 18000,\n " +
254+ " \" onwork_flex_time\" : 3600\n " +
255+ " },\n " +
256+ " {\n " +
257+ " \" offwork_after_time\" : 21600,\n " +
258+ " \" onwork_flex_time\" : 7200\n " +
259+ " }\n " +
260+ " ]\n " +
261+ " },\n " +
262+ " \" max_allow_arrive_early\" : 0,\n " +
263+ " \" max_allow_arrive_late\" : 0\n " +
264+ " }\n " +
265+ " ],\n " +
266+ " \" groupname\" : \" 打卡\" ,\n " +
267+ " \" need_photo\" : false\n " +
268+ "}" ;
269+
270+ WxCpCropCheckinOption option = WxCpGsonBuilder .create ().fromJson (jsonWithLateRule , WxCpCropCheckinOption .class );
271+ assertThat (option ).isNotNull ();
272+ assertThat (option .getCheckinDate ()).isNotNull ();
273+ assertThat (option .getCheckinDate ().size ()).isEqualTo (1 );
274+
275+ WxCpCheckinGroupBase .CheckinDate checkinDate = option .getCheckinDate ().get (0 );
276+ assertThat (checkinDate ).isNotNull ();
277+ assertThat (checkinDate .getAllowFlex ()).isFalse ();
278+ assertThat (checkinDate .getMaxAllowArriveEarly ()).isEqualTo (0 );
279+ assertThat (checkinDate .getMaxAllowArriveLate ()).isEqualTo (0 );
280+
281+ // Test late_rule field
282+ assertThat (checkinDate .getLateRule ()).isNotNull ();
283+ assertThat (checkinDate .getLateRule ().getOffWorkAfterTime ()).isEqualTo (3600 );
284+ assertThat (checkinDate .getLateRule ().getOnWorkFlexTime ()).isEqualTo (3600 );
285+ assertThat (checkinDate .getLateRule ().getAllowOffWorkAfterTime ()).isTrue ();
286+ assertThat (checkinDate .getLateRule ().getTimerules ()).isNotNull ();
287+ assertThat (checkinDate .getLateRule ().getTimerules ().size ()).isEqualTo (2 );
288+
289+ // Test timerules
290+ WxCpCheckinGroupBase .TimeRule firstRule = checkinDate .getLateRule ().getTimerules ().get (0 );
291+ assertThat (firstRule .getOffWorkAfterTime ()).isEqualTo (18000 );
292+ assertThat (firstRule .getOnWorkFlexTime ()).isEqualTo (3600 );
293+
294+ // Test CheckinTime fields
295+ assertThat (checkinDate .getCheckinTime ()).isNotNull ();
296+ assertThat (checkinDate .getCheckinTime ().size ()).isEqualTo (1 );
297+
298+ WxCpCheckinGroupBase .CheckinTime checkinTime = checkinDate .getCheckinTime ().get (0 );
299+ assertThat (checkinTime .getTimeId ()).isEqualTo (1 );
300+ assertThat (checkinTime .getRestBeginTime ()).isEqualTo (43200 );
301+ assertThat (checkinTime .getRestEndTime ()).isEqualTo (48600 );
302+ assertThat (checkinTime .getAllowRest ()).isTrue ();
303+ assertThat (checkinTime .getEarliestWorkSec ()).isEqualTo (21600 );
304+ assertThat (checkinTime .getLatestWorkSec ()).isEqualTo (64740 );
305+ assertThat (checkinTime .getEarliestOffWorkSec ()).isEqualTo (32460 );
306+ assertThat (checkinTime .getLatestOffWorkSec ()).isEqualTo (107940 );
307+ assertThat (checkinTime .getNoNeedCheckon ()).isFalse ();
308+ assertThat (checkinTime .getNoNeedCheckoff ()).isFalse ();
309+
310+ System .out .println ("Successfully parsed late_rule and new checkintime fields:" );
311+ System .out .println (gson .toJson (option ));
312+ }
313+
314+ /**
315+ * Test issue #3323 - full JSON from the issue report.
316+ */
317+ @ Test
318+ public void testIssue3323FullJson () {
319+ // Full JSON from issue #3323
320+ String issueJson = "{\n " +
321+ " \" grouptype\" : 1,\n " +
322+ " \" groupid\" : 1,\n " +
323+ " \" checkindate\" : [\n " +
324+ " {\n " +
325+ " \" workdays\" : [\n " +
326+ " 1,\n " +
327+ " 2,\n " +
328+ " 3,\n " +
329+ " 4,\n " +
330+ " 5\n " +
331+ " ],\n " +
332+ " \" checkintime\" : [\n " +
333+ " {\n " +
334+ " \" time_id\" : 1,\n " +
335+ " \" work_sec\" : 32400,\n " +
336+ " \" off_work_sec\" : 64800,\n " +
337+ " \" remind_work_sec\" : 31800,\n " +
338+ " \" remind_off_work_sec\" : 64800,\n " +
339+ " \" rest_begin_time\" : 43200,\n " +
340+ " \" rest_end_time\" : 48600,\n " +
341+ " \" allow_rest\" : true,\n " +
342+ " \" earliest_work_sec\" : 21600,\n " +
343+ " \" latest_work_sec\" : 64740,\n " +
344+ " \" earliest_off_work_sec\" : 32460,\n " +
345+ " \" latest_off_work_sec\" : 107940,\n " +
346+ " \" no_need_checkon\" : false,\n " +
347+ " \" no_need_checkoff\" : false\n " +
348+ " }\n " +
349+ " ],\n " +
350+ " \" noneed_offwork\" : false,\n " +
351+ " \" limit_aheadtime\" : 0,\n " +
352+ " \" flex_on_duty_time\" : 0,\n " +
353+ " \" flex_off_duty_time\" : 0,\n " +
354+ " \" allow_flex\" : false,\n " +
355+ " \" late_rule\" : {\n " +
356+ " \" offwork_after_time\" : 3600,\n " +
357+ " \" onwork_flex_time\" : 3600,\n " +
358+ " \" allow_offwork_after_time\" : true,\n " +
359+ " \" timerules\" : [\n " +
360+ " {\n " +
361+ " \" offwork_after_time\" : 18000,\n " +
362+ " \" onwork_flex_time\" : 3600\n " +
363+ " },\n " +
364+ " {\n " +
365+ " \" offwork_after_time\" : 21600,\n " +
366+ " \" onwork_flex_time\" : 7200\n " +
367+ " },\n " +
368+ " {\n " +
369+ " \" offwork_after_time\" : 28800,\n " +
370+ " \" onwork_flex_time\" : 10800\n " +
371+ " }\n " +
372+ " ]\n " +
373+ " },\n " +
374+ " \" max_allow_arrive_early\" : 0,\n " +
375+ " \" max_allow_arrive_late\" : 0\n " +
376+ " }\n " +
377+ " ],\n " +
378+ " \" spe_workdays\" : [],\n " +
379+ " \" spe_offdays\" : [],\n " +
380+ " \" sync_holidays\" : true,\n " +
381+ " \" groupname\" : \" 打卡\" ,\n " +
382+ " \" need_photo\" : false,\n " +
383+ " \" wifimac_infos\" : [],\n " +
384+ " \" note_can_use_local_pic\" : true,\n " +
385+ " \" allow_checkin_offworkday\" : false,\n " +
386+ " \" allow_apply_offworkday\" : false,\n " +
387+ " \" loc_infos\" : []\n " +
388+ " }" ;
389+
390+ WxCpCropCheckinOption option = WxCpGsonBuilder .create ().fromJson (issueJson , WxCpCropCheckinOption .class );
391+ assertThat (option ).isNotNull ();
392+ assertThat (option .getGroupId ()).isEqualTo (1 );
393+ assertThat (option .getGroupName ()).isEqualTo ("打卡" );
394+ assertThat (option .getCheckinDate ()).isNotNull ();
395+ assertThat (option .getCheckinDate ().size ()).isEqualTo (1 );
396+
397+ WxCpCheckinGroupBase .CheckinDate checkinDate = option .getCheckinDate ().get (0 );
398+ assertThat (checkinDate .getLateRule ()).isNotNull ();
399+ assertThat (checkinDate .getLateRule ().getOffWorkAfterTime ()).isEqualTo (3600 );
400+ assertThat (checkinDate .getLateRule ().getOnWorkFlexTime ()).isEqualTo (3600 );
401+ assertThat (checkinDate .getLateRule ().getAllowOffWorkAfterTime ()).isTrue ();
402+ assertThat (checkinDate .getLateRule ().getTimerules ()).isNotNull ();
403+ assertThat (checkinDate .getLateRule ().getTimerules ().size ()).isEqualTo (3 );
404+
405+ System .out .println ("✓ Successfully parsed full JSON from issue #3323" );
406+ System .out .println ("✓ Late Rule offwork_after_time: " + checkinDate .getLateRule ().getOffWorkAfterTime ());
407+ System .out .println ("✓ Late Rule onwork_flex_time: " + checkinDate .getLateRule ().getOnWorkFlexTime ());
408+ System .out .println ("✓ Late Rule allow_offwork_after_time: " + checkinDate .getLateRule ().getAllowOffWorkAfterTime ());
409+ System .out .println ("✓ Late Rule timerules count: " + checkinDate .getLateRule ().getTimerules ().size ());
410+ }
411+
212412 /**
213413 * Test get approval info.
214414 *
0 commit comments