Draft a copy of a transaction.
Devolve o body do create preenchido a partir da movimentação, sem gravar nada e sem consumir cota. Nunca traz payment_date nem reason: a cópia nasce não paga. Lançamento de cartão vira a COMPRA inteira: amount = valor total, installments = número de parcelas, competence = data da compra (a da linha, em compra legada) e reference da compra; o due_date é ignorado pelo create de cartão. Datas em AAAA-MM-DD.
Authorizations
Token da sessão no cabeçalho Authorization, no formato Bearer (mesmo esquema ApiKeyAuth do contrato).
Headers
company uuid
Path Parameters
Transaction ID
Response
OK
Allocations é o rateio por categoria + centro de custo (CERNE-267). PONTEIRO para distinguir os três estados do PUT (F2):
- ausente ou
null→ mantém as linhas gravadas (o front antigo nunca desfaz um rateio); []→ desfaz o rateio e usa coa_id/cost_center_id do topo (no POST é 400);- 2 a 20 linhas → substitui o rateio; coa_id/cost_center_id do topo podem ser omitidos e passam a ser os da 1ª linha (R9). Lançamento de cartão não aceita rateio (R8), nem a série POST /transactions/batch (R17). Regras das linhas:
- R1: de 2 a 20 linhas;
- R2: coa_id e cost_center_id obrigatórios; o par não se repete;
- R3: todas com amount OU todas com percentage, valores > 0 com no máximo 2 casas;
- R4: Σ percentage = 100,00; cada linha recebe floor(total × % / 100) e a última o resíduo; linha que resulta em 0,00 é recusada;
- R5: Σ amount = amount do lançamento, sem tolerância.
CostCenterID e BankAccountID seguem string (e não ponteiro): o corpo atual continua válido byte a byte, e ausência de conta deixou de ser erro por si só — passou a depender de haver, ou não, cartão no lugar dela.
CreditCardAccountID é a SEGUNDA origem possível (Decisão B). Aditivo: ausente, tudo se comporta exatamente como antes desta feature.
DueDate, Competence e PaymentDate são DateOnly (não time.Time): aceitam "AAAA-MM-DD" (Swagger) e RFC3339 (frontend web) — ver date_only.go.
Installments é PONTEIRO para distinguir "ausente" de "1". Os dois
significam à vista, mas só o ponteiro permite recusar installments
enviado junto com conta bancária — silenciar levaria o usuário a crer que
parcelou algo que não foi parcelado (mesma regra que a coluna Parcelas
do CSV tem na spec).
O TETO (24, decisão Q2) NÃO é validado aqui: quem o decide é creditcardrepo.validatePurchaseRequest, via ErrInstallmentsOutOfRange, e duplicar o número neste arquivo criaria duas fontes para o mesmo limite.
Reason é lido SÓ pelo PUT de lançamento de conta bancária (paid-transaction-reversal / T7): obrigatório quando a edição move dinheiro (valor, conta ou tipo de lançamento pago — RN7), ignorado quando não move. O POST de criação o ignora.