senal88's picture
chore: deploy web_comercial from monorepo
7a818d6 verified
import test from "node:test";
import assert from "node:assert/strict";
import {
calcularIndicadoresSecundario,
calcularSimulacao,
listarPerfisFluxoScpDefault,
montarFluxoClienteScp,
simularModoConversaoScpConsorcio,
simularSecundarioComPerfilScp,
} from "../src/index.js";
const baseInput = {
credito_desejado: 300000,
parametros: {
id_plano: "PADRAO",
nome_plano: "Plano Padrao Imovel",
prazo_meses: 180,
taxa_administracao_total: 0.15,
fundo_reserva_mensal: 0.0005,
seguro_prestamista: 0.035,
},
tem_lance: false,
};
test("calcula parcela integral com valores esperados", () => {
const result = calcularSimulacao(baseInput);
assert.equal(result.prazo, 180);
assert.equal(result.credito, 300000);
assert.ok(result.parcela_integral.total > 0);
assert.equal(Number(result.parcela_integral.fundo_comum.toFixed(2)), 1666.67);
});
test("calcula cenario com lance e reduz prazo", () => {
const result = calcularSimulacao({
...baseInput,
tem_lance: true,
lance_percentual: 0.3,
});
assert.ok(result.valor_lance);
assert.equal(result.valor_lance, 90000);
assert.ok(result.prazo_apos_lance);
assert.ok(result.prazo_apos_lance < result.prazo);
});
test("falha quando prazo_meses for invalido", () => {
assert.throws(() => {
calcularSimulacao({
...baseInput,
parametros: {
...baseInput.parametros,
prazo_meses: 0,
},
});
}, /prazo_meses/);
});
test("calcula payback do secundario com offset apos ultima contemplacao", () => {
const fluxos = [];
for (let i = 0; i < 10; i += 1) {
fluxos.push(-100);
}
for (let i = 0; i < 50; i += 1) {
fluxos.push(20);
}
const result = calcularIndicadoresSecundario({
fluxos_mensais: fluxos,
meses_pos_ultima_contemplacao: 3,
});
assert.equal(result.caixa_maximo_negativo, -1000);
assert.equal(result.payback_meses, 63);
assert.equal(result.regras_aplicadas.fee_sobre_volume_reduzido_70, true);
});
test("deduz portabilidade e fee com parcela reduzida em 70% do volume", () => {
const result = calcularIndicadoresSecundario({
fluxos_mensais: [-1000, 500, 700],
transacoes_portabilidade: [
{ valor: 100000, contemplada: true },
{ valor: 100000, contemplada: false },
],
volume_contratado: 300000,
fee_percentual: 0.02,
percentual_cartas_parcela_reduzida: 1,
});
assert.equal(result.custo_portabilidade, 1500);
assert.equal(result.custo_fee_parcela_reduzida, 4200);
assert.equal(result.custo_total_deducoes, 5700);
assert.equal(result.fluxo_ajustado[0], -6700);
});
test("valida entradas invalidas no secundario", () => {
assert.throws(() => {
calcularIndicadoresSecundario({
fluxos_mensais: [-100, 100],
percentual_cartas_parcela_reduzida: 1.2,
});
}, /percentual_cartas_parcela_reduzida/);
});
test("calcula tir mensal e anual no secundario", () => {
const result = calcularIndicadoresSecundario({
fluxos_mensais: [-1000, 1100],
});
assert.ok(result.tir_mensal !== null);
assert.ok(result.tir_anual !== null);
assert.ok(Math.abs(result.tir_mensal - 0.1) < 1e-6);
});
test("lista perfis SCP default com clientes entregues", () => {
const catalogo = listarPerfisFluxoScpDefault();
assert.ok(catalogo.clients.length >= 6);
assert.ok(catalogo.patterns.length >= 2);
assert.ok(catalogo.clients.find((c) => c.client_id === "extrato_investidor_6"));
});
test("monta fluxo SCP parametrizado por escala e deslocamento", () => {
const fluxo = montarFluxoClienteScp({
client_id: "extrato_investidor_6",
escala_fluxo: 0.5,
deslocamento_meses: 2,
novo_client_id: "cliente_novo",
novo_client_name: "Cliente Novo",
});
assert.equal(fluxo.client_id, "cliente_novo");
assert.equal(fluxo.client_name, "Cliente Novo");
assert.equal(fluxo.source_client_id, "extrato_investidor_6");
assert.ok(fluxo.pontos.length > 10);
assert.equal(fluxo.pontos[0].periodo, "2021-04-01");
});
test("simula secundario com perfil SCP default", () => {
const result = simularSecundarioComPerfilScp({
client_id: "extrato_investidor_6",
fee_percentual: 0.02,
volume_contratado: 100000,
percentual_cartas_parcela_reduzida: 0.5,
});
assert.equal(result.fluxo_cliente.client_id, "extrato_investidor_6");
assert.ok(result.fluxo_ajustado.length > 10);
assert.ok(typeof result.caixa_maximo_negativo === "number");
});
test("simula modo conversao fechado SCP -> imovel + secundario", () => {
const result = simularModoConversaoScpConsorcio({
client_id: "extrato_investidor_6",
valor_imovel_base: 600000,
desconto_imovel_percentual: 0.15,
percentual_entrada_imovel: 0.25,
agio_consorcio_percentual: 0.1,
taxa_custos_transacao_percentual: 0.02,
fee_percentual: 0.02,
volume_contratado: 120000,
percentual_cartas_parcela_reduzida: 0.5,
});
assert.ok(result.modo_conversao);
assert.equal(result.modo_conversao.valor_imovel_com_desconto, 510000);
assert.equal(result.modo_conversao.valor_entrada_imovel, 127500);
assert.ok(typeof result.modo_conversao.lucro_projetado_conversao === "number");
});