@neutron.co.id/pendidikan-operation 1.26.5 → 1.26.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/actions/akademik/action.presenceSessionStudent.cjs +1 -1
- package/build/actions/akademik/action.presenceSessionStudent.mjs +1 -1
- package/build/actions/akademik/index.d.ts +1 -0
- package/build/actions/akademik/studentReport/index.d.ts +2 -0
- package/build/actions/akademik/studentReport/syncStudentReport.action.cjs +310 -0
- package/build/actions/akademik/studentReport/syncStudentReport.action.d.ts +16 -0
- package/build/actions/akademik/studentReport/syncStudentReport.action.mjs +308 -0
- package/build/actions/akademik/studentReport/syncStudentReport.schema.cjs +14 -0
- package/build/actions/akademik/studentReport/syncStudentReport.schema.d.ts +17 -0
- package/build/actions/akademik/studentReport/syncStudentReport.schema.mjs +12 -0
- package/build/actions/penilaian/getGradingCount/index.d.ts +1 -0
- package/build/actions/penilaian/index.d.ts +2 -1
- package/build/actions/penilaian/refreshGrading/index.d.ts +2 -0
- package/build/actions/penilaian/refreshGrading/refreshGrading.action.cjs +44 -0
- package/build/actions/penilaian/refreshGrading/refreshGrading.action.d.ts +12 -0
- package/build/actions/penilaian/refreshGrading/refreshGrading.action.mjs +42 -0
- package/build/actions/penilaian/refreshGrading/refreshGrading.schema.cjs +9 -0
- package/build/actions/penilaian/refreshGrading/refreshGrading.schema.d.ts +8 -0
- package/build/actions/penilaian/refreshGrading/refreshGrading.schema.mjs +7 -0
- package/build/actions/rasionalisasi/action.addManyGradingComponent.cjs +0 -2
- package/build/actions/rasionalisasi/action.addManyGradingComponent.mjs +0 -2
- package/build/index.cjs +11 -1
- package/build/index.d.ts +9 -0
- package/build/index.mjs +8 -2
- package/build/providers/data/useImportData.cjs +5 -4
- package/build/providers/data/useImportData.mjs +5 -4
- package/build/providers/index.d.ts +1 -0
- package/build/providers/penilaian/index.d.ts +1 -0
- package/build/providers/penilaian/usePenilaian.cjs +92 -0
- package/build/providers/penilaian/usePenilaian.d.ts +6 -0
- package/build/providers/penilaian/usePenilaian.mjs +90 -0
- package/package.json +8 -8
- /package/build/actions/penilaian/{action.getGradingCount.cjs → getGradingCount/action.getGradingCount.cjs} +0 -0
- /package/build/actions/penilaian/{action.getGradingCount.d.ts → getGradingCount/action.getGradingCount.d.ts} +0 -0
- /package/build/actions/penilaian/{action.getGradingCount.mjs → getGradingCount/action.getGradingCount.mjs} +0 -0
|
@@ -34,7 +34,7 @@ const presenceSessionStudent = operation.Action.define({
|
|
|
34
34
|
data: {
|
|
35
35
|
classSessionId: input.sessionId,
|
|
36
36
|
studentId: input.studentId,
|
|
37
|
-
teacherId: input.teacherId,
|
|
37
|
+
// teacherId: input.teacherId,
|
|
38
38
|
classSessionBranchIds: session.branchIds,
|
|
39
39
|
presenceType: "student",
|
|
40
40
|
isAbsent: false,
|
|
@@ -32,7 +32,7 @@ const presenceSessionStudent = Action.define({
|
|
|
32
32
|
data: {
|
|
33
33
|
classSessionId: input.sessionId,
|
|
34
34
|
studentId: input.studentId,
|
|
35
|
-
teacherId: input.teacherId,
|
|
35
|
+
// teacherId: input.teacherId,
|
|
36
36
|
classSessionBranchIds: session.branchIds,
|
|
37
37
|
presenceType: "student",
|
|
38
38
|
isAbsent: false,
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const core = require('@neon.id/core');
|
|
4
|
+
const operation = require('@neon.id/operation');
|
|
5
|
+
const utils = require('@neon.id/utils');
|
|
6
|
+
const query = require('@neon.id/query');
|
|
7
|
+
|
|
8
|
+
const syncStudentReport = operation.Action.define({
|
|
9
|
+
key: "syncStudentReport",
|
|
10
|
+
name: "Sync Student Report",
|
|
11
|
+
type: "command",
|
|
12
|
+
category: "domain",
|
|
13
|
+
execute: async (input, stream) => {
|
|
14
|
+
utils.guard(stream, "streamRequired");
|
|
15
|
+
utils.guard(input, "inputRequired");
|
|
16
|
+
const dbs = stream.core.dbs;
|
|
17
|
+
const dbStudent = dbs["neu-akademik"].models["neu:akademik:student"];
|
|
18
|
+
const dbAttendance = dbs["neu-jadwal"].models["neu:jadwal:classAttendance"];
|
|
19
|
+
const dbConsultation = dbs["neu-jadwal"].models["neu:jadwal:classConsultation"];
|
|
20
|
+
const dbQuestion = dbs["neu-tanya"].models["neu:tanya:question"];
|
|
21
|
+
const dbCheckIn = dbs["neu-tempat"].models["neu:tempat:checkIn"];
|
|
22
|
+
const dbGrading = dbs["neu-penilaian"].models["neu:penilaian:grading"];
|
|
23
|
+
const resultGrading = await dbGrading.find({
|
|
24
|
+
studentId: input.studentId,
|
|
25
|
+
createdAt: {
|
|
26
|
+
$gte: input.startedAt,
|
|
27
|
+
$lte: input.endedAt
|
|
28
|
+
},
|
|
29
|
+
deletedAt: { $exists: false }
|
|
30
|
+
}).sort({ createdAt: -1 });
|
|
31
|
+
const gradingCount = resultGrading.length;
|
|
32
|
+
if (resultGrading.length > 0) {
|
|
33
|
+
await dbStudent.updateOne(
|
|
34
|
+
{ _id: input.studentId },
|
|
35
|
+
{
|
|
36
|
+
$set: {
|
|
37
|
+
totalGrading: gradingCount
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
} else {
|
|
42
|
+
await dbStudent.updateOne(
|
|
43
|
+
{ _id: input.studentId },
|
|
44
|
+
{
|
|
45
|
+
$set: {
|
|
46
|
+
totalGrading: gradingCount
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const resultAttendance = await dbAttendance.find({
|
|
52
|
+
studentId: input.studentId,
|
|
53
|
+
createdAt: {
|
|
54
|
+
$gte: input.startedAt,
|
|
55
|
+
$lte: input.endedAt
|
|
56
|
+
},
|
|
57
|
+
// isAbsent: { $exists: false, $ne: true },
|
|
58
|
+
deletedAt: { $exists: false }
|
|
59
|
+
}).sort({ createdAt: -1 });
|
|
60
|
+
const attendanceCount = resultAttendance.length;
|
|
61
|
+
const attendanceOffline = resultAttendance.filter((field) => field?.sessionType === "offline");
|
|
62
|
+
const totalAttendanceOffline = attendanceOffline.length;
|
|
63
|
+
const attendanceOnline = resultAttendance.filter((field) => field?.sessionType === "online");
|
|
64
|
+
const totalAttendanceOnline = attendanceOnline.length;
|
|
65
|
+
if (resultAttendance.length > 0) {
|
|
66
|
+
await dbStudent.updateOne(
|
|
67
|
+
{ _id: input.studentId },
|
|
68
|
+
{
|
|
69
|
+
$set: {
|
|
70
|
+
totalAttendance: attendanceCount,
|
|
71
|
+
attendanceOffline: totalAttendanceOffline,
|
|
72
|
+
attendanceOnline: totalAttendanceOnline
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
} else {
|
|
77
|
+
await dbStudent.updateOne(
|
|
78
|
+
{ _id: input.studentId },
|
|
79
|
+
{
|
|
80
|
+
$set: {
|
|
81
|
+
totalAttendance: attendanceCount,
|
|
82
|
+
attendanceOffline: totalAttendanceOffline,
|
|
83
|
+
attendanceOnline: totalAttendanceOnline
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const resultCheckIn = await dbCheckIn.find({
|
|
89
|
+
studentId: input.studentId,
|
|
90
|
+
checkInAt: {
|
|
91
|
+
$gte: input.startedAt,
|
|
92
|
+
$lte: input.endedAt
|
|
93
|
+
},
|
|
94
|
+
deletedAt: { $exists: false }
|
|
95
|
+
}).sort({ createdAt: -1 });
|
|
96
|
+
const checkInCount = resultCheckIn.length;
|
|
97
|
+
if (resultCheckIn.length > 0) {
|
|
98
|
+
await dbStudent.updateOne(
|
|
99
|
+
{ _id: input.studentId },
|
|
100
|
+
{
|
|
101
|
+
$set: {
|
|
102
|
+
totalCheckin: checkInCount
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
} else {
|
|
107
|
+
await dbStudent.updateOne(
|
|
108
|
+
{ _id: input.studentId },
|
|
109
|
+
{
|
|
110
|
+
$set: {
|
|
111
|
+
totalCheckin: checkInCount
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
const resultConsultation = await dbConsultation.find({
|
|
117
|
+
studentIds: { $in: input.studentId },
|
|
118
|
+
branchId: { $in: input.branchIds },
|
|
119
|
+
createdAt: {
|
|
120
|
+
$gte: input.startedAt,
|
|
121
|
+
$lte: input.endedAt
|
|
122
|
+
},
|
|
123
|
+
deletedAt: { $exists: false }
|
|
124
|
+
});
|
|
125
|
+
const consultationCount = resultConsultation.length;
|
|
126
|
+
if (resultConsultation.length > 0) {
|
|
127
|
+
await dbStudent.updateOne(
|
|
128
|
+
{ _id: input.studentId },
|
|
129
|
+
{
|
|
130
|
+
$set: {
|
|
131
|
+
totalConsultation: consultationCount
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
} else {
|
|
136
|
+
await dbStudent.updateOne(
|
|
137
|
+
{ _id: input.studentId },
|
|
138
|
+
{
|
|
139
|
+
$set: {
|
|
140
|
+
totalConsultation: consultationCount
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
const resultQuestion = await dbQuestion.find({
|
|
146
|
+
studentId: input.studentId,
|
|
147
|
+
branchIds: { $in: input.branchIds },
|
|
148
|
+
createdAt: {
|
|
149
|
+
$gte: input.startedAt,
|
|
150
|
+
$lte: input.endedAt
|
|
151
|
+
},
|
|
152
|
+
deletedAt: { $exists: false }
|
|
153
|
+
}).sort({ createdAt: -1 });
|
|
154
|
+
const questionCount = resultQuestion.length;
|
|
155
|
+
if (resultQuestion.length > 0) {
|
|
156
|
+
await dbStudent.updateOne(
|
|
157
|
+
{ _id: input.studentId },
|
|
158
|
+
{
|
|
159
|
+
$set: {
|
|
160
|
+
totalQuestion: questionCount
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
} else {
|
|
165
|
+
await dbStudent.updateOne(
|
|
166
|
+
{ _id: input.studentId },
|
|
167
|
+
{
|
|
168
|
+
$set: {
|
|
169
|
+
totalQuestion: questionCount
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
const resultSession = await stream.actions.data.count.execute({
|
|
175
|
+
model: "neu:jadwal:classSession",
|
|
176
|
+
query: query.Query.define({
|
|
177
|
+
filter: {
|
|
178
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
179
|
+
branchIds: { $in: input.branchIds },
|
|
180
|
+
studentIds: { $in: [input.studentId] }
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
}, stream);
|
|
184
|
+
const sessionCount = resultSession.payload?.data?.total || 0;
|
|
185
|
+
const resultSchedule = await stream.actions.data.getMany.execute({
|
|
186
|
+
model: "neu:jadwal:classSession",
|
|
187
|
+
query: query.Query.define({
|
|
188
|
+
filter: {
|
|
189
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
190
|
+
branchIds: { $in: input.branchIds },
|
|
191
|
+
studentIds: { $in: [input.studentId] }
|
|
192
|
+
},
|
|
193
|
+
fields: {
|
|
194
|
+
id: 1,
|
|
195
|
+
createdAt: 1,
|
|
196
|
+
startedAt: 1
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
}, stream);
|
|
200
|
+
const startedDates = resultSchedule?.payload?.data?.map((item) => {
|
|
201
|
+
return utils.DateUtil.format(new Date(item.startedAt), { format: "yyyy-MM-dd" });
|
|
202
|
+
});
|
|
203
|
+
const uniqueDays = new Set(startedDates);
|
|
204
|
+
const scheduleCount = uniqueDays.size;
|
|
205
|
+
const sessionOffline = await stream.actions.data.count.execute({
|
|
206
|
+
model: "neu:jadwal:classSession",
|
|
207
|
+
query: query.Query.define({
|
|
208
|
+
filter: {
|
|
209
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
210
|
+
branchIds: { $in: input.branchIds },
|
|
211
|
+
studentIds: { $in: [input.studentId] },
|
|
212
|
+
type: "offline"
|
|
213
|
+
}
|
|
214
|
+
})
|
|
215
|
+
}, stream);
|
|
216
|
+
const totalOffline = sessionOffline.payload?.data?.total || 0;
|
|
217
|
+
const sessionOnline = await stream.actions.data.count.execute({
|
|
218
|
+
model: "neu:jadwal:classSession",
|
|
219
|
+
query: query.Query.define({
|
|
220
|
+
filter: {
|
|
221
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
222
|
+
branchIds: { $in: input.branchIds },
|
|
223
|
+
studentIds: { $in: [input.studentId] },
|
|
224
|
+
type: "online"
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
}, stream);
|
|
228
|
+
const totalOnline = sessionOnline.payload?.data?.total || 0;
|
|
229
|
+
const sessionHybrid = await stream.actions.data.count.execute({
|
|
230
|
+
model: "neu:jadwal:classSession",
|
|
231
|
+
query: query.Query.define({
|
|
232
|
+
filter: {
|
|
233
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
234
|
+
branchIds: { $in: input.branchIds },
|
|
235
|
+
studentIds: { $in: [input.studentId] },
|
|
236
|
+
type: "hybrid"
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
}, stream);
|
|
240
|
+
const totalHybrid = sessionHybrid.payload?.data?.total || 0;
|
|
241
|
+
if (sessionCount > 0) {
|
|
242
|
+
await dbStudent.updateOne(
|
|
243
|
+
{ _id: input.studentId },
|
|
244
|
+
{
|
|
245
|
+
$set: {
|
|
246
|
+
totalSession: sessionCount,
|
|
247
|
+
sessionOffline: totalOffline,
|
|
248
|
+
sessionOnline: totalOnline,
|
|
249
|
+
sessionHybrid: totalHybrid,
|
|
250
|
+
daySession: scheduleCount
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
} else {
|
|
255
|
+
await dbStudent.updateOne(
|
|
256
|
+
{ _id: input.studentId },
|
|
257
|
+
{
|
|
258
|
+
$set: {
|
|
259
|
+
totalSession: sessionCount,
|
|
260
|
+
sessionOffline: totalOffline,
|
|
261
|
+
sessionOnline: totalOnline,
|
|
262
|
+
sessionHybrid: totalHybrid,
|
|
263
|
+
daySession: scheduleCount
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
const activityResult = await stream.actions.data.count.execute({
|
|
269
|
+
model: "neu:jadwal:classActivity",
|
|
270
|
+
query: query.Query.define({
|
|
271
|
+
filter: {
|
|
272
|
+
studentId: input.studentId,
|
|
273
|
+
createdAt: {
|
|
274
|
+
$gte: input.startedAt,
|
|
275
|
+
$lte: input.endedAt
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
}, stream);
|
|
280
|
+
const totalActivities = activityResult.payload?.data?.total || 0;
|
|
281
|
+
if (sessionCount > 0) {
|
|
282
|
+
await dbStudent.updateOne(
|
|
283
|
+
{ _id: input.studentId },
|
|
284
|
+
{
|
|
285
|
+
$set: {
|
|
286
|
+
totalActivity: totalActivities
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
} else {
|
|
291
|
+
await dbStudent.updateOne(
|
|
292
|
+
{ _id: input.studentId },
|
|
293
|
+
{
|
|
294
|
+
$set: {
|
|
295
|
+
totalActivity: totalActivities
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
return core.Result.ok({
|
|
301
|
+
state: "studentReportSync",
|
|
302
|
+
message: "Student Report has been sync.",
|
|
303
|
+
data: {
|
|
304
|
+
code: 1
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
exports.syncStudentReport = syncStudentReport;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Action } from '@neon.id/operation';
|
|
2
|
+
import type { z } from '@neon.id/z';
|
|
3
|
+
import type { StudentReportSchema } from './syncStudentReport.schema';
|
|
4
|
+
export type SyncStudentReportInput = z.parse<typeof StudentReportSchema>;
|
|
5
|
+
export interface SyncStudentReportOutput {
|
|
6
|
+
code: number;
|
|
7
|
+
}
|
|
8
|
+
export interface SyncStudentReportMeta {
|
|
9
|
+
}
|
|
10
|
+
export declare const syncStudentReport: Action<"syncStudentReport", {
|
|
11
|
+
branchIds?: string[] | undefined;
|
|
12
|
+
studentId?: string | undefined;
|
|
13
|
+
startedAt?: string | undefined;
|
|
14
|
+
endedAt?: string | undefined;
|
|
15
|
+
}, SyncStudentReportOutput, SyncStudentReportMeta>;
|
|
16
|
+
export type SyncStudentReportAction = typeof syncStudentReport;
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { Result } from '@neon.id/core';
|
|
2
|
+
import { Action } from '@neon.id/operation';
|
|
3
|
+
import { guard, DateUtil } from '@neon.id/utils';
|
|
4
|
+
import { Query } from '@neon.id/query';
|
|
5
|
+
|
|
6
|
+
const syncStudentReport = Action.define({
|
|
7
|
+
key: "syncStudentReport",
|
|
8
|
+
name: "Sync Student Report",
|
|
9
|
+
type: "command",
|
|
10
|
+
category: "domain",
|
|
11
|
+
execute: async (input, stream) => {
|
|
12
|
+
guard(stream, "streamRequired");
|
|
13
|
+
guard(input, "inputRequired");
|
|
14
|
+
const dbs = stream.core.dbs;
|
|
15
|
+
const dbStudent = dbs["neu-akademik"].models["neu:akademik:student"];
|
|
16
|
+
const dbAttendance = dbs["neu-jadwal"].models["neu:jadwal:classAttendance"];
|
|
17
|
+
const dbConsultation = dbs["neu-jadwal"].models["neu:jadwal:classConsultation"];
|
|
18
|
+
const dbQuestion = dbs["neu-tanya"].models["neu:tanya:question"];
|
|
19
|
+
const dbCheckIn = dbs["neu-tempat"].models["neu:tempat:checkIn"];
|
|
20
|
+
const dbGrading = dbs["neu-penilaian"].models["neu:penilaian:grading"];
|
|
21
|
+
const resultGrading = await dbGrading.find({
|
|
22
|
+
studentId: input.studentId,
|
|
23
|
+
createdAt: {
|
|
24
|
+
$gte: input.startedAt,
|
|
25
|
+
$lte: input.endedAt
|
|
26
|
+
},
|
|
27
|
+
deletedAt: { $exists: false }
|
|
28
|
+
}).sort({ createdAt: -1 });
|
|
29
|
+
const gradingCount = resultGrading.length;
|
|
30
|
+
if (resultGrading.length > 0) {
|
|
31
|
+
await dbStudent.updateOne(
|
|
32
|
+
{ _id: input.studentId },
|
|
33
|
+
{
|
|
34
|
+
$set: {
|
|
35
|
+
totalGrading: gradingCount
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
} else {
|
|
40
|
+
await dbStudent.updateOne(
|
|
41
|
+
{ _id: input.studentId },
|
|
42
|
+
{
|
|
43
|
+
$set: {
|
|
44
|
+
totalGrading: gradingCount
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const resultAttendance = await dbAttendance.find({
|
|
50
|
+
studentId: input.studentId,
|
|
51
|
+
createdAt: {
|
|
52
|
+
$gte: input.startedAt,
|
|
53
|
+
$lte: input.endedAt
|
|
54
|
+
},
|
|
55
|
+
// isAbsent: { $exists: false, $ne: true },
|
|
56
|
+
deletedAt: { $exists: false }
|
|
57
|
+
}).sort({ createdAt: -1 });
|
|
58
|
+
const attendanceCount = resultAttendance.length;
|
|
59
|
+
const attendanceOffline = resultAttendance.filter((field) => field?.sessionType === "offline");
|
|
60
|
+
const totalAttendanceOffline = attendanceOffline.length;
|
|
61
|
+
const attendanceOnline = resultAttendance.filter((field) => field?.sessionType === "online");
|
|
62
|
+
const totalAttendanceOnline = attendanceOnline.length;
|
|
63
|
+
if (resultAttendance.length > 0) {
|
|
64
|
+
await dbStudent.updateOne(
|
|
65
|
+
{ _id: input.studentId },
|
|
66
|
+
{
|
|
67
|
+
$set: {
|
|
68
|
+
totalAttendance: attendanceCount,
|
|
69
|
+
attendanceOffline: totalAttendanceOffline,
|
|
70
|
+
attendanceOnline: totalAttendanceOnline
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
} else {
|
|
75
|
+
await dbStudent.updateOne(
|
|
76
|
+
{ _id: input.studentId },
|
|
77
|
+
{
|
|
78
|
+
$set: {
|
|
79
|
+
totalAttendance: attendanceCount,
|
|
80
|
+
attendanceOffline: totalAttendanceOffline,
|
|
81
|
+
attendanceOnline: totalAttendanceOnline
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
const resultCheckIn = await dbCheckIn.find({
|
|
87
|
+
studentId: input.studentId,
|
|
88
|
+
checkInAt: {
|
|
89
|
+
$gte: input.startedAt,
|
|
90
|
+
$lte: input.endedAt
|
|
91
|
+
},
|
|
92
|
+
deletedAt: { $exists: false }
|
|
93
|
+
}).sort({ createdAt: -1 });
|
|
94
|
+
const checkInCount = resultCheckIn.length;
|
|
95
|
+
if (resultCheckIn.length > 0) {
|
|
96
|
+
await dbStudent.updateOne(
|
|
97
|
+
{ _id: input.studentId },
|
|
98
|
+
{
|
|
99
|
+
$set: {
|
|
100
|
+
totalCheckin: checkInCount
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
} else {
|
|
105
|
+
await dbStudent.updateOne(
|
|
106
|
+
{ _id: input.studentId },
|
|
107
|
+
{
|
|
108
|
+
$set: {
|
|
109
|
+
totalCheckin: checkInCount
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
const resultConsultation = await dbConsultation.find({
|
|
115
|
+
studentIds: { $in: input.studentId },
|
|
116
|
+
branchId: { $in: input.branchIds },
|
|
117
|
+
createdAt: {
|
|
118
|
+
$gte: input.startedAt,
|
|
119
|
+
$lte: input.endedAt
|
|
120
|
+
},
|
|
121
|
+
deletedAt: { $exists: false }
|
|
122
|
+
});
|
|
123
|
+
const consultationCount = resultConsultation.length;
|
|
124
|
+
if (resultConsultation.length > 0) {
|
|
125
|
+
await dbStudent.updateOne(
|
|
126
|
+
{ _id: input.studentId },
|
|
127
|
+
{
|
|
128
|
+
$set: {
|
|
129
|
+
totalConsultation: consultationCount
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
} else {
|
|
134
|
+
await dbStudent.updateOne(
|
|
135
|
+
{ _id: input.studentId },
|
|
136
|
+
{
|
|
137
|
+
$set: {
|
|
138
|
+
totalConsultation: consultationCount
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
const resultQuestion = await dbQuestion.find({
|
|
144
|
+
studentId: input.studentId,
|
|
145
|
+
branchIds: { $in: input.branchIds },
|
|
146
|
+
createdAt: {
|
|
147
|
+
$gte: input.startedAt,
|
|
148
|
+
$lte: input.endedAt
|
|
149
|
+
},
|
|
150
|
+
deletedAt: { $exists: false }
|
|
151
|
+
}).sort({ createdAt: -1 });
|
|
152
|
+
const questionCount = resultQuestion.length;
|
|
153
|
+
if (resultQuestion.length > 0) {
|
|
154
|
+
await dbStudent.updateOne(
|
|
155
|
+
{ _id: input.studentId },
|
|
156
|
+
{
|
|
157
|
+
$set: {
|
|
158
|
+
totalQuestion: questionCount
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
} else {
|
|
163
|
+
await dbStudent.updateOne(
|
|
164
|
+
{ _id: input.studentId },
|
|
165
|
+
{
|
|
166
|
+
$set: {
|
|
167
|
+
totalQuestion: questionCount
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
const resultSession = await stream.actions.data.count.execute({
|
|
173
|
+
model: "neu:jadwal:classSession",
|
|
174
|
+
query: Query.define({
|
|
175
|
+
filter: {
|
|
176
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
177
|
+
branchIds: { $in: input.branchIds },
|
|
178
|
+
studentIds: { $in: [input.studentId] }
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
}, stream);
|
|
182
|
+
const sessionCount = resultSession.payload?.data?.total || 0;
|
|
183
|
+
const resultSchedule = await stream.actions.data.getMany.execute({
|
|
184
|
+
model: "neu:jadwal:classSession",
|
|
185
|
+
query: Query.define({
|
|
186
|
+
filter: {
|
|
187
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
188
|
+
branchIds: { $in: input.branchIds },
|
|
189
|
+
studentIds: { $in: [input.studentId] }
|
|
190
|
+
},
|
|
191
|
+
fields: {
|
|
192
|
+
id: 1,
|
|
193
|
+
createdAt: 1,
|
|
194
|
+
startedAt: 1
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
}, stream);
|
|
198
|
+
const startedDates = resultSchedule?.payload?.data?.map((item) => {
|
|
199
|
+
return DateUtil.format(new Date(item.startedAt), { format: "yyyy-MM-dd" });
|
|
200
|
+
});
|
|
201
|
+
const uniqueDays = new Set(startedDates);
|
|
202
|
+
const scheduleCount = uniqueDays.size;
|
|
203
|
+
const sessionOffline = await stream.actions.data.count.execute({
|
|
204
|
+
model: "neu:jadwal:classSession",
|
|
205
|
+
query: Query.define({
|
|
206
|
+
filter: {
|
|
207
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
208
|
+
branchIds: { $in: input.branchIds },
|
|
209
|
+
studentIds: { $in: [input.studentId] },
|
|
210
|
+
type: "offline"
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
}, stream);
|
|
214
|
+
const totalOffline = sessionOffline.payload?.data?.total || 0;
|
|
215
|
+
const sessionOnline = await stream.actions.data.count.execute({
|
|
216
|
+
model: "neu:jadwal:classSession",
|
|
217
|
+
query: Query.define({
|
|
218
|
+
filter: {
|
|
219
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
220
|
+
branchIds: { $in: input.branchIds },
|
|
221
|
+
studentIds: { $in: [input.studentId] },
|
|
222
|
+
type: "online"
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
}, stream);
|
|
226
|
+
const totalOnline = sessionOnline.payload?.data?.total || 0;
|
|
227
|
+
const sessionHybrid = await stream.actions.data.count.execute({
|
|
228
|
+
model: "neu:jadwal:classSession",
|
|
229
|
+
query: Query.define({
|
|
230
|
+
filter: {
|
|
231
|
+
startedAt: { $gte: input.startedAt, $lte: input.endedAt },
|
|
232
|
+
branchIds: { $in: input.branchIds },
|
|
233
|
+
studentIds: { $in: [input.studentId] },
|
|
234
|
+
type: "hybrid"
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
}, stream);
|
|
238
|
+
const totalHybrid = sessionHybrid.payload?.data?.total || 0;
|
|
239
|
+
if (sessionCount > 0) {
|
|
240
|
+
await dbStudent.updateOne(
|
|
241
|
+
{ _id: input.studentId },
|
|
242
|
+
{
|
|
243
|
+
$set: {
|
|
244
|
+
totalSession: sessionCount,
|
|
245
|
+
sessionOffline: totalOffline,
|
|
246
|
+
sessionOnline: totalOnline,
|
|
247
|
+
sessionHybrid: totalHybrid,
|
|
248
|
+
daySession: scheduleCount
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
} else {
|
|
253
|
+
await dbStudent.updateOne(
|
|
254
|
+
{ _id: input.studentId },
|
|
255
|
+
{
|
|
256
|
+
$set: {
|
|
257
|
+
totalSession: sessionCount,
|
|
258
|
+
sessionOffline: totalOffline,
|
|
259
|
+
sessionOnline: totalOnline,
|
|
260
|
+
sessionHybrid: totalHybrid,
|
|
261
|
+
daySession: scheduleCount
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
const activityResult = await stream.actions.data.count.execute({
|
|
267
|
+
model: "neu:jadwal:classActivity",
|
|
268
|
+
query: Query.define({
|
|
269
|
+
filter: {
|
|
270
|
+
studentId: input.studentId,
|
|
271
|
+
createdAt: {
|
|
272
|
+
$gte: input.startedAt,
|
|
273
|
+
$lte: input.endedAt
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
})
|
|
277
|
+
}, stream);
|
|
278
|
+
const totalActivities = activityResult.payload?.data?.total || 0;
|
|
279
|
+
if (sessionCount > 0) {
|
|
280
|
+
await dbStudent.updateOne(
|
|
281
|
+
{ _id: input.studentId },
|
|
282
|
+
{
|
|
283
|
+
$set: {
|
|
284
|
+
totalActivity: totalActivities
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
);
|
|
288
|
+
} else {
|
|
289
|
+
await dbStudent.updateOne(
|
|
290
|
+
{ _id: input.studentId },
|
|
291
|
+
{
|
|
292
|
+
$set: {
|
|
293
|
+
totalActivity: totalActivities
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
return Result.ok({
|
|
299
|
+
state: "studentReportSync",
|
|
300
|
+
message: "Student Report has been sync.",
|
|
301
|
+
data: {
|
|
302
|
+
code: 1
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
export { syncStudentReport };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const z = require('@neon.id/z');
|
|
4
|
+
|
|
5
|
+
const StudentReportSchema = z.z.object({
|
|
6
|
+
studentId: z.z.string().optional().explain({ label: "Student ID" }),
|
|
7
|
+
branchIds: z.z.array(z.z.string()).optional().explain({
|
|
8
|
+
label: "Branch IDs"
|
|
9
|
+
}),
|
|
10
|
+
startedAt: z.z.string().datetime().optional().explain({ label: "Started At" }),
|
|
11
|
+
endedAt: z.z.string().datetime().optional().explain({ label: "Ended At" })
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
exports.StudentReportSchema = StudentReportSchema;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from '@neon.id/z';
|
|
2
|
+
export declare const StudentReportSchema: z.ZodObject<{
|
|
3
|
+
studentId: z.ZodOptional<z.ZodString>;
|
|
4
|
+
branchIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
5
|
+
startedAt: z.ZodOptional<z.ZodString>;
|
|
6
|
+
endedAt: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
branchIds?: string[] | undefined;
|
|
9
|
+
studentId?: string | undefined;
|
|
10
|
+
startedAt?: string | undefined;
|
|
11
|
+
endedAt?: string | undefined;
|
|
12
|
+
}, {
|
|
13
|
+
branchIds?: string[] | undefined;
|
|
14
|
+
studentId?: string | undefined;
|
|
15
|
+
startedAt?: string | undefined;
|
|
16
|
+
endedAt?: string | undefined;
|
|
17
|
+
}>;
|