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
« prev ^ index » next coverage.py v7.6.2, created at 2024-10-10 03:02 +0300
1from typing import Annotated
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
34statistics_router = APIRouter(prefix="/statistics", tags=["statistics"])
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)
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 )
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 )
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 )