Aprovações de desconto
Lista as solicitações de desconto que passaram da alçada do representante e registra a decisão do painel (aprovar, recusar ou ajustar).
Quando um representante pede um desconto maior do que ele pode dar sozinho (veja Alçadas e régua), a plataforma abre uma solicitação de aprovação e retém o pedido. Alguém com autoridade decide: aprova o desconto pedido, ajusta para um valor menor, ou recusa. O app do representante e o painel veem a mesma fila. Estas duas rotas são a visão do painel.
Elas aceitam também o privilégio approve_rep_discounts, para quem só aprova e não gerencia o resto dos representantes.
Listar as solicitações
/api/v1/admin/trade-reps/approvalsAdminLista as solicitações de aprovação de desconto
Parâmetros de consulta
statusstringpadrão: pendingpendingapprovedrejectedadjustedallpending. all traz todas.{
"approvals": [
{
"id": "7c1e9b52-3a64-4f08-a1d2-5b6c7d8e9f01",
"client_submission_id": "app-sub-8841",
"rep_id": 2,
"rep_name": "João da Silva",
"customer_id": "472e2c31-fa7a-4d06-84c9-f832619bcdbd",
"customer_name": "Mariana Cavalcanti",
"cluster_code": "M",
"requested_discount_bp": 1200,
"order_total_cents": 480000,
"justification_code": "competitor_price",
"justification_text": "Concorrente oferece 12% neste item.",
"required_level": 1,
"current_level": 1,
"status": "pending",
"order_id": "4cb4cd7c-e817-48b3-b4a0-2f99f856a50b",
"order_number": "19611",
"created_at": "2026-10-11T14:00:00Z",
"updated_at": "2026-10-11T14:00:00Z",
"steps": [
{ "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d", "request_id": "7c1e9b52-3a64-4f08-a1d2-5b6c7d8e9f01", "level": 1, "approver_name": "Carlos Lima", "created_at": "2026-10-11T14:00:00Z" }
]
}
]
}Campos da resposta
approvalsarrayapprovals[].iduuidapprovals[].client_submission_idstringapprovals[].rep_idintegerapprovals[].rep_namestringapprovals[].customer_iduuidapprovals[].customer_namestringapprovals[].cluster_codestringPMGapprovals[].requested_discount_bpintegerapprovals[].granted_discount_bpintegerapprovals[].order_total_centsintegerapprovals[].margin_bpintegerapprovals[].justification_codestringapprovals[].justification_textstringapprovals[].required_levelintegerapprovals[].current_levelintegerapprovals[].statusstringpendingapprovedrejectedadjustedapprovals[].order_idstringapprovals[].order_numberstringapprovals[].order_linesarrayproduct_id, sku, name, quantity, unit_price_cents, discount_bp, line_total_cents.approvals[].customerobjectapprovals[].stepsarraylevel, approver_name, decision, granted_discount_bp, comment, decided_at.approvals[].order_effectstringapprovals[].reopened_draftobjectapprovals[].source_channelstringapprovals[].expires_atstringapprovals[].created_atstringapprovals[].updated_atstringDecidir uma solicitação
Funciona em qualquer nível: o painel decide direto, sem precisar passar pela cascata. A decisão grava a assinatura, fecha a solicitação e age sobre o pedido retido (libera, reprecifica ou devolve para correção).
/api/v1/admin/trade-reps/approvals/{id}/decideAdminDecide uma solicitação de desconto
Parâmetros de caminho
iduuidobrigatórioapprovals[].id).Corpo da requisição
decisionstringobrigatórioapprovedrejectedadjustedapproved: concede o desconto pedido. adjusted: concede um valor diferente (granted_discount_bp). rejected: nega. Maiúsculas e espaços são ignorados.granted_discount_bpintegeradjusted. Em approved, se omitido, vale o desconto pedido.commentstringcurl -X POST "$BASE_URL/api/v1/admin/trade-reps/approvals/7c1e9b52-3a64-4f08-a1d2-5b6c7d8e9f01/decide" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"decision": "adjusted", "granted_discount_bp": 800, "comment": "Concedo 8% pela margem do pedido."}'A resposta (200) é a solicitação já decidida, no mesmo formato da lista, com status, granted_discount_bp e order_effect preenchidos.
Erros
| Status | Quando | Corpo de exemplo |
|---|---|---|
| 400 | decision fora de approved/rejected/adjusted. | {"error":"invalid_decision","detail":"Decisão inválida (use approved, rejected ou adjusted)"} |
| 400 | adjusted sem granted_discount_bp. | {"error":"granted_discount_required","detail":"Informe o desconto concedido para ajustar"} |
| 400 | Corpo não é JSON, ou outra falha na decisão (por exemplo, fim da vigência de uma campanha de faseamento). | {"error":"decide_failed","detail":"..."} |
| 404 | Solicitação não existe. | {"error":"approval_not_found","detail":"Solicitação não encontrada"} |
| 409 | A solicitação já foi decidida. | {"error":"approval_not_pending","detail":"Solicitação já foi decidida"} |
| 409 | adjusted em pedido que já tem pagamento (não dá para reprecificar). | {"error":"order_already_paid","detail":"O pedido já tem pagamento; o ajuste de desconto não pode reprecificá-lo"} |
| 401 / 403 | Sem token, módulo desligado ou sem manage_trade_reps/manage_vendors/approve_rep_discounts. | {"error":"module_disabled","module":"trade-reps"} |
As mensagens do detail saem em português, como o servidor devolve.