@@ -255,7 +255,12 @@ async def read_activities(
255255 "as" : "member" ,
256256 "cond" : {
257257 "$or" : [
258- {"$eq" : ["$$member.status" , "" if not audit else "pending" ]},
258+ {
259+ "$eq" : [
260+ "$$member.status" ,
261+ "" if not audit else "pending" ,
262+ ]
263+ },
259264 ]
260265 },
261266 }
@@ -273,7 +278,20 @@ async def read_activities(
273278 "members.status" : True ,
274279 }
275280 },
276- {"$sort" : {"_id" : - 1 }},
281+ {
282+ "$addFields" : {
283+ "pendingCount" : {
284+ "$size" : {
285+ "$filter" : {
286+ "input" : "$members" ,
287+ "as" : "member" ,
288+ "cond" : {"$eq" : ["$$member.status" , "pending" ]},
289+ }
290+ }
291+ }
292+ }
293+ },
294+ {"$sort" : {"pendingCount" : - 1 , "_id" : - 1 }},
277295 {"$skip" : 0 if page == - 1 else (page - 1 ) * perpage },
278296 {"$limit" : 0 if page == - 1 else perpage },
279297 ]
@@ -308,13 +326,117 @@ async def read_activity(activity_oid: str, user=Depends(get_current_user)):
308326 Return activity
309327 """
310328 # Read activity
311- activity = await db .zvms .activities .find_one (
312- {"_id" : validate_object_id (activity_oid )},
329+ pipeline = [
313330 {
314- "members.impression" : False ,
315- "members.history" : False ,
331+ "$match" : {
332+ "_id" : validate_object_id (activity_oid ),
333+ }
316334 },
317- )
335+ {
336+ "$addFields" : {
337+ "members" : {
338+ "$map" : {
339+ "input" : "$members" ,
340+ "as" : "member" ,
341+ "in" : {
342+ "$mergeObjects" : [
343+ "$$member" ,
344+ {
345+ "sortKey" : {
346+ "$switch" : {
347+ "branches" : [
348+ {
349+ "case" : {
350+ "$eq" : [
351+ "$$member.status" ,
352+ "pending" ,
353+ ]
354+ },
355+ "then" : 0 ,
356+ },
357+ {
358+ "case" : {
359+ "$eq" : [
360+ "$$member.status" ,
361+ "rejected" ,
362+ ]
363+ },
364+ "then" : 1 ,
365+ },
366+ {
367+ "case" : {
368+ "$eq" : [
369+ "$$member.status" ,
370+ "refused" ,
371+ ]
372+ },
373+ "then" : 2 ,
374+ },
375+ {
376+ "case" : {
377+ "$eq" : [
378+ "$$member.status" ,
379+ "effective" ,
380+ ]
381+ },
382+ "then" : 3 ,
383+ },
384+ {
385+ "case" : {
386+ "$eq" : [
387+ "$$member.status" ,
388+ "draft" ,
389+ ]
390+ },
391+ "then" : 4 ,
392+ },
393+ ],
394+ "default" : 5 , # handle unexpected statuses
395+ }
396+ }
397+ },
398+ ]
399+ },
400+ }
401+ }
402+ }
403+ },
404+ {
405+ "$set" : {
406+ "members" : {
407+ "$sortArray" : {"input" : "$members" , "sortBy" : {"sortKey" : 1 }}
408+ }
409+ }
410+ },
411+ {
412+ "$project" : {
413+ "members" : {
414+ "$map" : {
415+ "input" : "$members" ,
416+ "as" : "member" ,
417+ "in" : {
418+ "_id" : "$$member._id" ,
419+ "status" : "$$member.status" ,
420+ "duration" : "$$member.duration" ,
421+ "mode" : "$$member.mode" ,
422+ },
423+ }
424+ },
425+ "name" : True ,
426+ "description" : True ,
427+ "status" : True ,
428+ "date" : True ,
429+ "type" : True ,
430+ "special" : True ,
431+ "creator" : True ,
432+ "updatedAt" : True ,
433+ "registration" : True ,
434+ }
435+ },
436+ ]
437+ activity = await db .zvms .activities .aggregate (pipeline ).to_list (None )
438+ activity = activity [0 ]
439+
318440 if not activity :
319441 raise HTTPException (status_code = 404 , detail = "Activity not found" )
320442
@@ -362,7 +484,6 @@ async def user_activity_signup(
362484 detail = "Permission denied, cannot be appended to this activity." ,
363485 )
364486 elif "department" in user ["per" ] or "admin" in user ["per" ]:
365- print ("this one" )
366487 status = (
367488 MemberActivityStatus .effective
368489 if activity ["type" ] == ActivityType .special
@@ -526,18 +647,20 @@ async def user_impression_edit(
526647 if user_activity is None :
527648 raise HTTPException (status_code = 404 , detail = "User not found in activity" )
528649
529- user_activity = user_activity [' members' ][0 ]
650+ user_activity = user_activity [" members" ][0 ]
530651
531- history = ActivityMemberHistory (impression = user_activity ['impression' ],
532- duration = user_activity ['duration' ],
533- action = user_activity ['status' ],
534- # ISO-8601
535- time = datetime .now ().isoformat (),
536- actioner = user ['id' ])
652+ history = ActivityMemberHistory (
653+ impression = user_activity ["impression" ],
654+ duration = user_activity ["duration" ],
655+ action = user_activity ["status" ],
656+ # ISO-8601
657+ time = datetime .now ().isoformat (),
658+ actioner = user ["id" ],
659+ )
537660
538661 await db .zvms .activities .update_one (
539662 {"_id" : validate_object_id (activity_oid ), "members._id" : id },
540- {"$push" : {"members.$.history" : history .model_dump ()}}
663+ {"$push" : {"members.$.history" : history .model_dump ()}},
541664 )
542665
543666 return {
@@ -628,18 +751,20 @@ async def user_status_edit(
628751 if user_activity is None :
629752 raise HTTPException (status_code = 404 , detail = "User not found in activity" )
630753
631- user_activity = user_activity [' members' ][0 ]
754+ user_activity = user_activity [" members" ][0 ]
632755
633- history = ActivityMemberHistory (impression = user_activity ['impression' ],
634- duration = user_activity ['duration' ],
635- action = user_activity ['status' ],
636- # ISO-8601
637- time = datetime .now ().isoformat (),
638- actioner = user ['id' ])
756+ history = ActivityMemberHistory (
757+ impression = user_activity ["impression" ],
758+ duration = user_activity ["duration" ],
759+ action = user_activity ["status" ],
760+ # ISO-8601
761+ time = datetime .now ().isoformat (),
762+ actioner = user ["id" ],
763+ )
639764
640765 await db .zvms .activities .update_one (
641766 {"_id" : validate_object_id (activity_oid ), "members._id" : user_oid },
642- {"$push" : {"members.$.history" : history .model_dump ()}}
767+ {"$push" : {"members.$.history" : history .model_dump ()}},
643768 )
644769
645770 return {
@@ -654,7 +779,10 @@ class PutDuration(BaseModel):
654779
655780@router .put ("/{activity_oid}/member/{user_oid}/duration" )
656781async def user_duration_edit (
657- activity_oid : str , user_oid : str , payload : PutDuration , user = Depends (get_current_user )
782+ activity_oid : str ,
783+ user_oid : str ,
784+ payload : PutDuration ,
785+ user = Depends (get_current_user ),
658786):
659787 """
660788 User modify activity status
@@ -681,10 +809,7 @@ async def user_duration_edit(
681809 raise HTTPException (status_code = 400 , detail = "User not in activity" )
682810
683811 # Check user status
684- if (
685- "auditor" not in user ["per" ]
686- and "admin" not in user ["per" ]
687- ):
812+ if "auditor" not in user ["per" ] and "admin" not in user ["per" ]:
688813 raise HTTPException (
689814 status_code = 403 , detail = "Permission denied, not enough permission"
690815 )
@@ -706,7 +831,6 @@ async def user_duration_edit(
706831 if member is None :
707832 raise HTTPException (status_code = 400 , detail = "User not in activity" )
708833
709-
710834 # Modify user duration
711835 await db .zvms .activities .update_one (
712836 {"_id" : validate_object_id (activity_oid ), "members._id" : user_oid },
@@ -720,18 +844,20 @@ async def user_duration_edit(
720844 if user_activity is None :
721845 raise HTTPException (status_code = 404 , detail = "User not found in activity" )
722846
723- user_activity = user_activity [' members' ][0 ]
847+ user_activity = user_activity [" members" ][0 ]
724848
725- history = ActivityMemberHistory (impression = user_activity ['impression' ],
726- duration = user_activity ['duration' ],
727- action = user_activity ['status' ],
728- # ISO-8601
729- time = datetime .now ().isoformat (),
730- actioner = user ['id' ])
849+ history = ActivityMemberHistory (
850+ impression = user_activity ["impression" ],
851+ duration = user_activity ["duration" ],
852+ action = user_activity ["status" ],
853+ # ISO-8601
854+ time = datetime .now ().isoformat (),
855+ actioner = user ["id" ],
856+ )
731857
732858 await db .zvms .activities .update_one (
733859 {"_id" : validate_object_id (activity_oid ), "members._id" : user_oid },
734- {"$push" : {"members.$.history" : history .model_dump ()}}
860+ {"$push" : {"members.$.history" : history .model_dump ()}},
735861 )
736862
737863 return {
0 commit comments