Coverage for api/endpoints/statistics.py: 100%

38 statements  

« prev     ^ index     » next       coverage.py v7.6.2, created at 2024-10-10 03:02 +0300

1from typing import Annotated 

2 

3from fastapi import APIRouter, Depends 

4from handlers.orders.recommendations import get_recommendations_data 

5from keycloak import idp 

6from mongodb import ( 

7 archive_col, 

8 bids_col, 

9 buf_col, 

10 drivers_col, 

11 orders_col, 

12 orgs_col, 

13 trailers_col, 

14 trucks_col, 

15) 

16from sotrans_models.models.misc.statistics import ( 

17 CarriersStatisticsModel, 

18 CarrierStatistics, 

19 ChartModel, 

20 StatisticsModel, 

21 VerificationsStatisticsModel, 

22) 

23from sotrans_models.models.orders.order import ( 

24 OrderDBModel, 

25 OrderStatus, 

26 StageType, 

27) 

28from sotrans_models.models.organizations import OrganizationDBModel 

29from sotrans_models.models.roles import SotransRole 

30from sotrans_models.models.users import SotransOIDCUserModel 

31from utils.dt_utils import get_current_datetime, get_period_num_of_months_back 

32from utils.helper import get_org_oid 

33 

34statistics_router = APIRouter(prefix="/statistics", tags=["statistics"]) 

35 

36 

37@statistics_router.get("/company") 

38async def get_company_statistics( 

39 _: Annotated[ 

40 SotransOIDCUserModel, 

41 Depends( 

42 idp.get_current_user( 

43 required_role_names=[SotransRole.company_logistician] 

44 ) 

45 ), 

46 ], 

47) -> StatisticsModel: 

48 volume_total = [ 

49 vt["volume_total"] 

50 async for vt in archive_col.collection.aggregate( 

51 [ 

52 { 

53 "$group": { 

54 "_id": None, 

55 "volume_total": {"$sum": "$end_price"}, 

56 }, 

57 }, 

58 {"$project": {"_id": 0, "volume_total": "$volume_total"}}, 

59 ] 

60 ) 

61 ] 

62 volume_chart = [] 

63 new_carriers_chart = [] 

64 cdt = get_current_datetime() 

65 for m in range(6): 

66 dt, upper_dt = get_period_num_of_months_back(m, cdt) 

67 

68 volume_comps = await archive_col.find_batch( 

69 { 

70 OrderDBModel.current_stage.type: StageType.ready.value, 

71 OrderDBModel.current_stage.timestamp: { 

72 "$lt": upper_dt, 

73 "$gte": dt, 

74 }, 

75 } 

76 ) 

77 volume_chart.append( 

78 ChartModel( 

79 key=str(dt.month), 

80 value=sum(OrderDBModel(**o).end_price for o in volume_comps), 

81 ) 

82 ) 

83 carriers_in_month = await orgs_col.count( 

84 { 

85 OrganizationDBModel.created_at: { 

86 "$lt": upper_dt, 

87 "$gte": dt, 

88 } 

89 } 

90 ) 

91 new_carriers_chart.append( 

92 ChartModel(key=str(dt.month), value=carriers_in_month) 

93 ) 

94 return StatisticsModel( 

95 archive_count=await archive_col.count({}), 

96 active_count=await orders_col.count( 

97 {"status": OrderStatus.active.value} 

98 ), 

99 canceled_count=await orders_col.count( 

100 {"status": OrderStatus.canceled.value} 

101 ), 

102 appointment_count=await orders_col.count( 

103 {"status": OrderStatus.appointment.value} 

104 ), 

105 volume_total=volume_total[0] if volume_total else 0, 

106 unverified_count=await orders_col.count( 

107 {"status": OrderStatus.unverified.value} 

108 ), 

109 confirmed_count=await orders_col.count( 

110 {"status": OrderStatus.confirmed.value} 

111 ), 

112 exchange_count=await orders_col.count( 

113 {"status": OrderStatus.exchange.value} 

114 ), 

115 buffer_count=await buf_col.count({}), 

116 carriers=CarriersStatisticsModel( 

117 registered_count=await orgs_col.count({}), 

118 new_count=await orgs_col.count( 

119 { 

120 "created_at": { 

121 "$gt": get_current_datetime(-7 * 24 * 60 * 60) 

122 } 

123 } 

124 ), 

125 active_bids_count=await bids_col.count({}), 

126 ), 

127 verifications=VerificationsStatisticsModel( 

128 carriers_ready_for_check_count=await orgs_col.count( 

129 {"documents.1": {"$exists": True}} 

130 ), 

131 drivers_ready_for_check_count=await drivers_col.count( 

132 {"documents.1": {"$exists": True}} 

133 ), 

134 trucks_ready_for_check_count=await trucks_col.count( 

135 {"documents.0": {"$exists": True}} 

136 ), 

137 trailers_ready_for_check_count=await trailers_col.count( 

138 {"documents.0": {"$exists": True}} 

139 ), 

140 ), 

141 volume_chart=volume_chart, 

142 new_carriers_chart=new_carriers_chart, 

143 ) 

144 

145 

146@statistics_router.get("/carrier") 

147async def get_carriers_main( 

148 user: Annotated[ 

149 SotransOIDCUserModel, 

150 Depends( 

151 idp.get_current_user( 

152 required_role_names=[SotransRole.carrier_logistician] 

153 ) 

154 ), 

155 ], 

156) -> CarrierStatistics: 

157 carrier_q = {OrderDBModel.carrier.id: get_org_oid(user)} 

158 recommendation_count = len( 

159 await get_recommendations_data(get_org_oid(user)) 

160 ) 

161 volume_total = [ 

162 vt["volume_total"] 

163 async for vt in archive_col.collection.aggregate( 

164 [ 

165 {"$match": carrier_q}, 

166 { 

167 "$group": { 

168 "_id": None, 

169 "volume_total": {"$sum": "$end_price"}, 

170 }, 

171 }, 

172 {"$project": {"_id": 0, "volume_total": "$volume_total"}}, 

173 ] 

174 ) 

175 ] 

176 volume_chart = [] 

177 cdt = get_current_datetime() 

178 for m in range(6): 

179 dt, upper_dt = get_period_num_of_months_back(m, cdt) 

180 volume_comps = await archive_col.find_batch( 

181 { 

182 OrderDBModel.current_stage.type: StageType.ready.value, 

183 OrderDBModel.current_stage.timestamp: { 

184 "$lt": upper_dt, 

185 "$gte": dt, 

186 }, 

187 } 

188 | carrier_q 

189 ) 

190 volume_chart.append( 

191 ChartModel( 

192 key=str(dt.month), 

193 value=sum(OrderDBModel(**o).end_price for o in volume_comps), 

194 ) 

195 ) 

196 

197 return CarrierStatistics( 

198 exchange_orders=await orders_col.count( 

199 {OrderDBModel.status: OrderStatus.exchange.value} 

200 ), 

201 confirmed_orders=await orders_col.count( 

202 {OrderDBModel.status: OrderStatus.confirmed.value} | carrier_q 

203 ), 

204 volume=volume_total[0] if volume_total else 0, 

205 recommendation_orders=recommendation_count, 

206 volume_chart=volume_chart, 

207 )