@@ -23,23 +23,34 @@ public async Task<List<WorkingHours>> List(int dayStartHour, Expression<Func<Pun
23
23
var records = await PunchRecordService . Instance . List ( predicate ) ;
24
24
return await List ( dayStartHour , records ) ;
25
25
}
26
- public async Task < List < WorkingHours > > List ( int dayStartHour , IEnumerable < PunchRecord > punchRecords )
26
+ public async Task < List < WorkingHours > > List ( int dayStartHour , IEnumerable < PunchRecord > punchRecordEnumerables )
27
27
{
28
28
var result = new List < WorkingHours > ( ) ;
29
- if ( punchRecords == null || punchRecords . Count ( ) == 0 )
29
+ if ( punchRecordEnumerables == null || punchRecordEnumerables . Count ( ) == 0 )
30
30
{
31
31
return result ;
32
32
}
33
- var lastRecord = punchRecords . FirstOrDefault ( ) ;
33
+ var lastRecord = punchRecordEnumerables . FirstOrDefault ( ) ;
34
+ var punchRecords = punchRecordEnumerables . ToList ( ) ;
34
35
var lastDate = lastRecord . PunchDateTime ;
35
36
var monthStartDay = new DateTime ( lastDate . Year , lastDate . Month , 1 ) ;
36
37
var monthEndDay = monthStartDay . AddMonths ( 1 ) . AddDays ( - 1 ) ;
37
38
var now = DateTime . Now ;
38
39
var startUnix = monthStartDay . TimestampUnix ( ) ;
39
40
var endUnix = monthEndDay . TimestampUnix ( ) ;
40
41
var workingTimeRanges = await WorkingTimeRangeService . Instance . Items ( startUnix , endUnix ) ;
41
- var attendanceRecords = await AttendanceRecordService . Instance . List ( m => m . StartTime >= startUnix && m . StartTime < endUnix && AttendanceTypeService . AskForLeaveIds . Contains ( m . AttendanceTypeId ) ) ;
42
+ var attendances = await AttendanceRecordService . Instance . List ( m => m . StartTime >= startUnix && m . StartTime < endUnix && AttendanceTypeService . AskForLeaveIds . Contains ( m . AttendanceTypeId ) ) ;
43
+ var punchInRecords = await AttendanceRecordService . Instance . List ( m => m . StartTime >= startUnix && m . StartTime < endUnix && ( m . EndTime <= 0 || m . EndTime < endUnix ) && AttendanceTypeService . PunchInRecordIds . Contains ( m . AttendanceTypeId ) ) ;
44
+ var attendanceRecords = ParseAttendance ( attendances , workingTimeRanges ) ;
42
45
var calendars = await CalendarService . Instance . ListAll ( m => m . Date >= startUnix && m . Date < endUnix ) ;
46
+ foreach ( var item in punchInRecords )
47
+ {
48
+ if ( item . StartTime <= 0 && item . EndTime <= 0 ) continue ;
49
+ punchRecords . Add ( new PunchRecord ( )
50
+ {
51
+ PunchTime = item . StartTime > 0 ? item . StartTime : item . EndTime ,
52
+ } ) ;
53
+ }
43
54
for ( var i = 1 ; i <= monthEndDay . Day ; i ++ )
44
55
{
45
56
if ( monthEndDay . Year == now . Year && monthEndDay . Month == now . Month && i > now . Day )
@@ -61,6 +72,60 @@ public async Task<List<WorkingHours>> List(int dayStartHour, IEnumerable<PunchRe
61
72
return result . OrderByDescending ( m => m . WorkingDate ) . ToList ( ) ;
62
73
}
63
74
75
+ private List < AttendanceRecord > ParseAttendance ( List < AttendanceRecord > attendances , Dictionary < long , WorkingTimeRangeItems > workingTimeRanges )
76
+ {
77
+ var result = new List < AttendanceRecord > ( ) ;
78
+ foreach ( var item in attendances )
79
+ {
80
+ var startDate = item . StartDateTime ;
81
+ var endDate = item . EndDateTime ;
82
+ var startDateUnix = startDate ? . TimestampUnix ( ) ?? 0 ;
83
+ var endDateUnix = endDate ? . TimestampUnix ( ) ?? 0 ;
84
+ var diff = endDateUnix - startDateUnix ;
85
+ if ( diff > DateTimeTools . DaySeconds )
86
+ {
87
+ var ranges = GetDateRanges ( startDate . Value , endDate . Value , workingTimeRanges ) ;
88
+ foreach ( var range in ranges )
89
+ {
90
+ result . Add ( new AttendanceRecord ( )
91
+ {
92
+ AttendanceId = item . AttendanceId ,
93
+ AttendanceTypeId = item . AttendanceTypeId ,
94
+ AttendanceType = item . AttendanceType ,
95
+ UserId = item . UserId ,
96
+ StartTime = range . Item1 ,
97
+ EndTime = range . Item2 ,
98
+ AttendanceTime = item . AttendanceTime ,
99
+ Remark = item . Remark
100
+ } ) ;
101
+ }
102
+ }
103
+ else
104
+ {
105
+ result . Add ( item ) ;
106
+ }
107
+ }
108
+ return result ;
109
+ }
110
+
111
+ private List < ( int , int ) > GetDateRanges ( DateTime startTime , DateTime endTime , Dictionary < long , WorkingTimeRangeItems > workingTimeRanges )
112
+ {
113
+ var result = new List < ( int , int ) > ( ) ;
114
+ var endTimeUnix = endTime . TimestampUnix ( ) ;
115
+ for ( var start = startTime ; start < endTime ; start = start . AddDays ( 1 ) )
116
+ {
117
+ var dateUnix = start . Date . TimestampUnix ( ) ;
118
+ if ( ! workingTimeRanges . TryGetValue ( dateUnix , out WorkingTimeRangeItems work ) )
119
+ {
120
+ continue ;
121
+ }
122
+ var startWorkDate = new DateTime ( start . Year , start . Month , start . Day , work . Work . StartHour , work . Work . StartMinute , 0 ) ;
123
+ var endWorkDate = new DateTime ( start . Year , start . Month , start . Day , work . Work . EndHour , work . Work . EndMinute , 0 ) ;
124
+ result . Add ( ( Math . Max ( startWorkDate . TimestampUnix ( ) , start . TimestampUnix ( ) ) , Math . Min ( endWorkDate . TimestampUnix ( ) , endTimeUnix ) ) ) ;
125
+ }
126
+ return result ;
127
+ }
128
+
64
129
private List < AttendanceRecord > GetAttendanceRecords ( List < AttendanceRecord > attendanceRecords , long timeStart , long timeEnd , WorkingTimeRangeItems workingTime )
65
130
{
66
131
var currentRecords = attendanceRecords . Where ( m => m . StartTime >= timeStart && m . StartTime < timeEnd ) . ToList ( ) ;
@@ -73,7 +138,7 @@ private List<AttendanceRecord> GetAttendanceRecords(List<AttendanceRecord> atten
73
138
var startWorkDate = new DateTime ( date . Year , date . Month , date . Day , workingTime . Work . StartHour , 0 , 0 ) ;
74
139
if ( currentRecords . Count == 0 )
75
140
{
76
- var currentCrossRecords = attendanceRecords . Where ( m => m . StartTime < timeStart && m . EndTime > timeStart ) . ToList ( ) ;
141
+ var currentCrossRecords = attendanceRecords . Where ( m => m . StartTime <= timeStart && m . EndTime >= timeStart ) . ToList ( ) ;
77
142
foreach ( var item in currentCrossRecords )
78
143
{
79
144
item . StartTime = Math . Max ( item . StartTime , startWorkDate . TimestampUnix ( ) ) ;
0 commit comments