import hashlib import httpx from typing import List, Any from core.config import settings from schemas.order import OrderResponse, OrderItem def _get_summary_string(json_data: Any) -> str: """Рекурсивная конкатенация значений для формирования MD5 подписи.""" summary = "" if isinstance(json_data, dict): for key in sorted(json_data.keys()): summary += _get_summary_string(json_data[key]) elif isinstance(json_data, list): for item in json_data: summary += _get_summary_string(item) else: if isinstance(json_data, bool): summary += "1" if json_data else "" elif json_data is not None: summary += str(json_data) return summary async def fetch_cod_orders(status_name: str = "APPROVED") -> List[OrderResponse]: payload = { "apikey": settings.CRM_API_KEY, "object": "Orders", "method": "GetOrders", "params": { "sid": settings.CRM_STORE_SID, "key": settings.CRM_STORE_KEY, "Status": status_name, "ReturnWaybill": True, "ReturnGoods": True, "ReturnTotals": True } } # Формирование контрольной суммы MD5 summary_string = _get_summary_string(payload) string_to_hash = summary_string + settings.CRM_API_SECRET payload["md5sum"] = hashlib.md5(string_to_hash.encode('utf-8')).hexdigest() headers = {'Content-Type': 'application/json; charset=utf-8'} async with httpx.AsyncClient() as client: response = await client.post(settings.CRM_API_URL, json=payload, headers=headers) response.raise_for_status() raw_data = response.json() parsed_orders = [] # 1. Берем данные из ключа "result" (а не "orders") orders_list = raw_data.get("result", []) for order in orders_list: # 2. Собираем товары из массива Goods items = [] for item in order.get("Goods", []): items.append( OrderItem( name=item.get("Name", ""), quantity=float(item.get("Quantity", 1.0)), price=float(item.get("Price", 0.0)) ) ) # 3. Извлекаем итоговую сумму из вложенного объекта Total.Amount total_info = order.get("Total", {}) total_amount = float(total_info.get("Amount", 0.0)) # 4. Формируем объект ответа для Pydantic parsed_orders.append( OrderResponse( id=str(order.get("ID")), client_name=order.get("RecipientDName", "Неизвестно"), client_phone=order.get("RecipientPhone", ""), ttn=order.get("Waybill_Number", ""), cod_amount=total_amount, fiscal_status="pending", items=items ) ) return parsed_orders