21
21
)
22
22
from aleph .services .cost import (
23
23
_get_product_price_type ,
24
- _get_settings ,
25
24
get_detailed_costs ,
26
25
get_payment_type ,
27
26
get_total_and_detailed_costs ,
28
27
get_total_and_detailed_costs_from_db ,
29
28
)
30
29
from aleph .services .pricing_utils import get_pricing_timeline
30
+ from aleph .toolkit .constants import DEFAULT_SETTINGS_AGGREGATE
31
31
from aleph .toolkit .costs import format_cost_str
32
32
from aleph .types .db_session import DbSession
33
33
from aleph .types .message_status import MessageStatus
34
+ from aleph .types .settings import Settings
34
35
from aleph .web .controllers .app_state_getters import (
35
36
get_session_factory_from_request ,
36
37
get_storage_service_from_request ,
@@ -174,7 +175,7 @@ async def message_price_estimate(request: web.Request):
174
175
175
176
async def recalculate_message_costs (request : web .Request ):
176
177
"""Force recalculation of message costs in chronological order with historical pricing.
177
-
178
+
178
179
This endpoint will:
179
180
1. Get all messages that need cost recalculation (if item_hash provided, just that message)
180
181
2. Get the pricing timeline to track price changes over time
@@ -183,15 +184,15 @@ async def recalculate_message_costs(request: web.Request):
183
184
5. Delete existing cost entries and recalculate with historical pricing
184
185
6. Store the new cost calculations
185
186
"""
186
-
187
+
187
188
session_factory = get_session_factory_from_request (request )
188
-
189
+
189
190
# Check if a specific message hash was provided
190
191
item_hash_param = request .match_info .get ("item_hash" )
191
-
192
+
192
193
with session_factory () as session :
193
194
messages_to_recalculate : List [MessageDb ] = []
194
-
195
+
195
196
if item_hash_param :
196
197
# Recalculate costs for a specific message
197
198
try :
@@ -203,78 +204,99 @@ async def recalculate_message_costs(request: web.Request):
203
204
# Recalculate costs for all executable messages, ordered by time (oldest first)
204
205
select_stmt = (
205
206
select (MessageDb )
206
- .where (MessageDb .type .in_ ([MessageType .instance , MessageType .program , MessageType .store ]))
207
+ .where (
208
+ MessageDb .type .in_ (
209
+ [MessageType .instance , MessageType .program , MessageType .store ]
210
+ )
211
+ )
207
212
.order_by (MessageDb .time .asc ())
208
213
)
209
214
result = session .execute (select_stmt )
210
215
messages_to_recalculate = result .scalars ().all ()
211
-
216
+
212
217
if not messages_to_recalculate :
213
218
return web .json_response (
214
- {"message" : "No messages found for cost recalculation" , "recalculated_count" : 0 }
219
+ {
220
+ "message" : "No messages found for cost recalculation" ,
221
+ "recalculated_count" : 0 ,
222
+ }
215
223
)
216
-
224
+
217
225
# Get the pricing timeline to track price changes over time
218
226
pricing_timeline = get_pricing_timeline (session )
219
227
LOGGER .info (f"Found { len (pricing_timeline )} pricing changes in timeline" )
220
-
228
+
221
229
recalculated_count = 0
222
230
errors = []
223
231
current_pricing_model = None
224
232
current_pricing_index = 0
225
-
233
+
226
234
for message in messages_to_recalculate :
227
235
try :
228
236
# Find the applicable pricing model for this message's timestamp
229
- while (current_pricing_index < len (pricing_timeline ) - 1 and
230
- pricing_timeline [current_pricing_index + 1 ][0 ] <= message .time ):
237
+ while (
238
+ current_pricing_index < len (pricing_timeline ) - 1
239
+ and pricing_timeline [current_pricing_index + 1 ][0 ] <= message .time
240
+ ):
231
241
current_pricing_index += 1
232
-
242
+
233
243
current_pricing_model = pricing_timeline [current_pricing_index ][1 ]
234
244
pricing_timestamp = pricing_timeline [current_pricing_index ][0 ]
235
-
236
- LOGGER .debug (f"Message { message .item_hash } at { message .time } using pricing from { pricing_timestamp } " )
237
-
245
+
246
+ LOGGER .debug (
247
+ f"Message { message .item_hash } at { message .time } using pricing from { pricing_timestamp } "
248
+ )
249
+
238
250
# Delete existing cost entries for this message
239
251
delete_costs_for_message (session , message .item_hash )
240
-
252
+
241
253
# Get the message content and determine product type
242
254
content : ExecutableContent = message .parsed_content
243
- product_type = _get_product_price_type (content , None , current_pricing_model )
244
-
255
+
256
+ # TODO: Calculate settings timeline
257
+ settings = Settings .from_aggregate (DEFAULT_SETTINGS_AGGREGATE )
258
+
259
+ product_type = _get_product_price_type (
260
+ content , settings , current_pricing_model
261
+ )
262
+
245
263
# Get the pricing for this specific product type
246
264
if product_type not in current_pricing_model :
247
- LOGGER .warning (f"Product type { product_type } not found in pricing model for message { message .item_hash } " )
265
+ LOGGER .warning (
266
+ f"Product type { product_type } not found in pricing model for message { message .item_hash } "
267
+ )
248
268
continue
249
-
269
+
250
270
pricing = current_pricing_model [product_type ]
251
-
271
+
252
272
# Calculate new costs using the historical pricing model
253
- new_costs = get_detailed_costs (session , content , message .item_hash , pricing )
254
-
273
+ new_costs = get_detailed_costs (
274
+ session , content , message .item_hash , pricing
275
+ )
276
+
255
277
if new_costs :
256
278
# Store the new cost calculations
257
279
upsert_stmt = make_costs_upsert_query (new_costs )
258
280
session .execute (upsert_stmt )
259
-
281
+
260
282
recalculated_count += 1
261
-
283
+
262
284
except Exception as e :
263
285
error_msg = f"Failed to recalculate costs for message { message .item_hash } : { str (e )} "
264
286
LOGGER .error (error_msg )
265
287
errors .append ({"item_hash" : message .item_hash , "error" : str (e )})
266
-
288
+
267
289
# Commit all changes
268
290
session .commit ()
269
-
291
+
270
292
response_data = {
271
293
"message" : "Cost recalculation completed with historical pricing" ,
272
294
"recalculated_count" : recalculated_count ,
273
295
"total_messages" : len (messages_to_recalculate ),
274
- "pricing_changes_found" : len (pricing_timeline )
296
+ "pricing_changes_found" : len (pricing_timeline ),
275
297
}
276
-
298
+
277
299
if errors :
278
300
response_data ["errors" ] = errors
279
-
301
+
280
302
return web .json_response (response_data )
0 commit comments