Um período fechado é imutável
Fechar escreve uma linhaBILL registrando o que foi faturado. Ela nunca é reescrita.
Um reembolso que cai depois, um recibo tardio, uma rate corrigida a posteriori — nenhum deles altera
um período fechado. O painel re-executa o resumo, compara-o com o valor armazenado e mostra a
diferença como uma credit note contra o próximo período.
A linha BILL não move dinheiro
delta registra o valor faturado — negativo, porque é o que a account consumiu. Mas a linha é
inerte.
O poll de recharge do gateway seleciona apenas RECHARGE e TRANSFER, portanto nada nunca aplica
um BILL. Arrears nunca entram em account_balance.balance, que mantém sua restrição não-negativa
e seu significado único: dinheiro disponível para gastar.
Para o que a linha é estruturalmente carregadora é para a janela. A linha BILL mais recente —
max(created_at) WHERE entry_type = 'BILL' — é o início do período não faturado. Portanto,
fechar é o que devolve o headroom de uma conta postpaid.
Fechar duas vezes é um conflito, não uma segunda fatura
A referência é determinística:uq_balance_ledger_ref é único onde não é nulo, portanto o mesmo período não pode ser fechado duas
vezes.
Determinístico de propósito — dois operadores clicando ao mesmo tempo devem colidir, e um pedido
retentado não deve produzir uma duplicata. O label é YYYY-MM ou um intervalo de datas, e não pode
conter um dois-pontos, portanto o último dois-pontos divide a referência de volta e um account id
contendo dois-pontos ainda faz round-trip.
De que um statement é computado
A fatura é uma função pura decdr_submit sobre uma janela semiaberta. Ela nunca lê o contador
postpaid, nunca lê account_balance e nunca lê o ledger.
Portanto, a única coisa que pode tornar uma fatura errada é uma linha cdr_submit ausente ou extra.
Janelas semiabertas
Um período cobre[start, end) — início inclusivo, fim exclusivo. Uma mensagem exatamente na
meia-noite da fronteira pertence ao período posterior, e pertence a exatamente um.
Essa é a propriedade que vale a pena verificar em qualquer query que você escreva: BETWEEN em SQL
é inclusivo nos dois extremos e vai contar em dobro uma mensagem de fronteira em dois statements.
A ordem que funciona
1
Deixe o período terminar
Cifras faturáveis ficam finais no momento em que o dia termina. Billing é sobre
submitted.2
Revise antes de fechar
O resumo é uma query viva até que você a feche. Este é o último ponto em que uma correção é
uma edição em vez de uma credit note.
3
Feche
Uma linha
BILL, idempotente na referência.4
Deixe correções posteriores serem credit notes
Elas são visíveis, atribuíveis, e caem no próximo período em vez de silenciosamente alterar um
número que o cliente já pagou.
Relacionado
Postpaid
Limites de crédito, e por que fechar devolve headroom.
Uso e retenção
O que sobrevive depois que os call records são purgados.