next-finance-mcp 0.9.21 → 0.9.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +6 -0
- package/dist/client.js +59 -39
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -121,7 +121,10 @@ export declare function buscarComprasProduto(opts?: FiltroComprasProduto): Promi
|
|
|
121
121
|
fornecedor: string;
|
|
122
122
|
moeda: string;
|
|
123
123
|
valor: number;
|
|
124
|
+
quantidade: number;
|
|
125
|
+
valor_total: number;
|
|
124
126
|
data: string;
|
|
127
|
+
observacao: string;
|
|
125
128
|
}[];
|
|
126
129
|
paginacao: {
|
|
127
130
|
pagina: number;
|
|
@@ -200,6 +203,9 @@ export interface ItemDespesaSlim {
|
|
|
200
203
|
valor: number;
|
|
201
204
|
desconto: number;
|
|
202
205
|
valor_total: number;
|
|
206
|
+
valor_bruto?: number;
|
|
207
|
+
valor_total_bruto?: number;
|
|
208
|
+
desconto_aplicado?: number;
|
|
203
209
|
}
|
|
204
210
|
export interface DespesaSlim {
|
|
205
211
|
data: string;
|
package/dist/client.js
CHANGED
|
@@ -851,15 +851,22 @@ export async function buscarComprasProduto(opts = {}) {
|
|
|
851
851
|
const total = items.length;
|
|
852
852
|
const offset = (pagina - 1) * limite;
|
|
853
853
|
const paginados = items.slice(offset, offset + limite);
|
|
854
|
-
// Slim: apenas campos legíveis — sem IDs
|
|
854
|
+
// Slim: apenas campos legíveis — sem IDs.
|
|
855
|
+
// Nota: o endpoint /api/ProdutoBusiness/FiltrarCompra retorna o produto cadastrado
|
|
856
|
+
// (agregação por produto). Não traz a Despesa pai, então NÃO há como ratear desconto
|
|
857
|
+
// a nível de documento aqui. Use ultimo_preco_produto para obter o preço REAL pago
|
|
858
|
+
// (que cruza com Despesa/FiltrarDespesaServProd e aplica desconto proporcional).
|
|
855
859
|
const compras = paginados.map(item => {
|
|
856
860
|
const prod = item["ProdutoBusiness"];
|
|
857
861
|
return {
|
|
858
|
-
produto: String(prod?.["Nome"] ?? ""),
|
|
862
|
+
produto: String(prod?.["Descricao"] ?? prod?.["Nome"] ?? item["Codigo"] ?? ""),
|
|
859
863
|
fornecedor: String(item["PessoaNome"] ?? ""),
|
|
860
864
|
moeda: String(item["MoedaNome"] ?? "BRL"),
|
|
861
|
-
valor: Number(item["Valor"] ?? 0),
|
|
865
|
+
valor: Number(item["Valor"] ?? 0), // preço bruto unitário (sem ratear desconto)
|
|
866
|
+
quantidade: Number(item["Quantidade"] ?? 0),
|
|
867
|
+
valor_total: Number(item["ValorTotal"] ?? 0),
|
|
862
868
|
data: String(item["DataAtualizacao"] ?? "").slice(0, 10),
|
|
869
|
+
observacao: "Preço bruto sem desconto da nota. Para preço real pago, use 'ultimo_preco_produto'.",
|
|
863
870
|
};
|
|
864
871
|
});
|
|
865
872
|
return {
|
|
@@ -1088,15 +1095,43 @@ async function resolverIdFornecedor(nome) {
|
|
|
1088
1095
|
const primeiro = arr[0];
|
|
1089
1096
|
return String(primeiro["Id"] ?? "");
|
|
1090
1097
|
}
|
|
1091
|
-
|
|
1098
|
+
/** Calcula valores REAIS (com desconto da nota distribuído) para um item de DespesaServProd.
|
|
1099
|
+
* Pode receber a Despesa pai inline (do FiltrarDespesaServProd) ou separadamente. */
|
|
1100
|
+
function aplicarDescontoProporcional(item, despesa) {
|
|
1101
|
+
const qtd = Number(item["Quantidade"] ?? 0);
|
|
1102
|
+
const valorBruto = Number(item["Valor"] ?? 0);
|
|
1103
|
+
const totalBruto = Number(item["ValorTotal"] ?? (qtd > 0 ? qtd * valorBruto : valorBruto));
|
|
1104
|
+
if (!despesa)
|
|
1105
|
+
return { precoUnitario: valorBruto, valorTotal: totalBruto };
|
|
1106
|
+
const despBruto = Number(despesa["Valor"] ?? 0);
|
|
1107
|
+
const despLiquido = Number(despesa["ValorLiquido"] ?? despBruto);
|
|
1108
|
+
if (despBruto <= 0 || Math.abs(despBruto - despLiquido) < 0.01) {
|
|
1109
|
+
return { precoUnitario: valorBruto, valorTotal: totalBruto };
|
|
1110
|
+
}
|
|
1111
|
+
const fator = despLiquido / despBruto;
|
|
1112
|
+
const totalReal = Math.round(totalBruto * fator * 100) / 100;
|
|
1113
|
+
const precoReal = qtd > 0 ? Math.round((totalReal / qtd) * 100) / 100 : valorBruto * fator;
|
|
1114
|
+
return {
|
|
1115
|
+
precoUnitario: precoReal,
|
|
1116
|
+
valorTotal: totalReal,
|
|
1117
|
+
descontoAplicado: Math.round((totalBruto - totalReal) * 100) / 100,
|
|
1118
|
+
precoUnitarioBruto: valorBruto,
|
|
1119
|
+
valorTotalBruto: totalBruto,
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
function slimItemDespesa(i, despesa) {
|
|
1123
|
+
const calc = aplicarDescontoProporcional(i, despesa);
|
|
1092
1124
|
return {
|
|
1093
1125
|
descricao: String(i["DescricaoServProd"] ?? "").trim(),
|
|
1094
1126
|
codigo: i["Codigo"] ? String(i["Codigo"]).trim() : undefined,
|
|
1095
1127
|
quantidade: Number(i["Quantidade"] ?? 0),
|
|
1096
1128
|
unidade: i["UnidadeMedida"] ? String(i["UnidadeMedida"]).trim() : undefined,
|
|
1097
|
-
valor:
|
|
1129
|
+
valor: calc.precoUnitario,
|
|
1098
1130
|
desconto: Number(i["Desconto"] ?? 0),
|
|
1099
|
-
valor_total:
|
|
1131
|
+
valor_total: calc.valorTotal,
|
|
1132
|
+
valor_bruto: calc.precoUnitarioBruto,
|
|
1133
|
+
valor_total_bruto: calc.valorTotalBruto,
|
|
1134
|
+
desconto_aplicado: calc.descontoAplicado,
|
|
1100
1135
|
};
|
|
1101
1136
|
}
|
|
1102
1137
|
function slimDespesa(d, comItens) {
|
|
@@ -1110,7 +1145,8 @@ function slimDespesa(d, comItens) {
|
|
|
1110
1145
|
valor_liquido: Number(d["ValorLiquido"] ?? 0),
|
|
1111
1146
|
};
|
|
1112
1147
|
if (comItens && itensRaw.length > 0) {
|
|
1113
|
-
|
|
1148
|
+
// Passa a despesa pai (d) pra distribuir descontos proporcionalmente
|
|
1149
|
+
result.itens = itensRaw.map(i => slimItemDespesa(i, d));
|
|
1114
1150
|
}
|
|
1115
1151
|
return result;
|
|
1116
1152
|
}
|
|
@@ -1179,19 +1215,23 @@ export async function buscarItensDespesa(opts = {}) {
|
|
|
1179
1215
|
const total = itens.length;
|
|
1180
1216
|
const inicio = (pagina - 1) * limite;
|
|
1181
1217
|
const resultado = itens.slice(inicio, inicio + limite).map(i => {
|
|
1182
|
-
const despesa = i["Despesa"] ??
|
|
1218
|
+
const despesa = i["Despesa"] ?? null;
|
|
1219
|
+
const calc = aplicarDescontoProporcional(i, despesa);
|
|
1183
1220
|
return {
|
|
1184
1221
|
descricao: String(i["DescricaoServProd"] ?? "").trim(),
|
|
1185
1222
|
codigo: i["Codigo"] ? String(i["Codigo"]).trim() : undefined,
|
|
1186
1223
|
quantidade: Number(i["Quantidade"] ?? 0),
|
|
1187
1224
|
unidade: i["UnidadeMedida"] ? String(i["UnidadeMedida"]).trim() : undefined,
|
|
1188
|
-
valor:
|
|
1225
|
+
valor: calc.precoUnitario, // REAL pago
|
|
1189
1226
|
desconto: Number(i["Desconto"] ?? 0),
|
|
1190
|
-
valor_total:
|
|
1227
|
+
valor_total: calc.valorTotal, // REAL pago
|
|
1228
|
+
valor_bruto: calc.precoUnitarioBruto,
|
|
1229
|
+
valor_total_bruto: calc.valorTotalBruto,
|
|
1230
|
+
desconto_aplicado: calc.descontoAplicado,
|
|
1191
1231
|
// Dados do documento pai — sem IDs
|
|
1192
|
-
data: String(despesa["Data"] ?? "").slice(0, 10),
|
|
1193
|
-
numero: String(despesa["Numero"] ?? "").trim(),
|
|
1194
|
-
fornecedor: String(despesa["PessoaNome"] ?? "").trim(),
|
|
1232
|
+
data: String(despesa?.["Data"] ?? "").slice(0, 10),
|
|
1233
|
+
numero: String(despesa?.["Numero"] ?? "").trim(),
|
|
1234
|
+
fornecedor: String(despesa?.["PessoaNome"] ?? "").trim(),
|
|
1195
1235
|
};
|
|
1196
1236
|
});
|
|
1197
1237
|
return {
|
|
@@ -1541,36 +1581,16 @@ export async function ultimoPrecoProduto(opts) {
|
|
|
1541
1581
|
const dataIso = String(it["DataAtualizacao"] ?? "");
|
|
1542
1582
|
const despesa = it["Despesa"] ?? null;
|
|
1543
1583
|
const data = dataIso || String(despesa?.["Data"] ?? "");
|
|
1544
|
-
const
|
|
1545
|
-
const valorBruto = Number(it["Valor"] ?? 0);
|
|
1546
|
-
const totalBruto = Number(it["ValorTotal"] ?? (qtd > 0 ? qtd * valorBruto : valorBruto));
|
|
1547
|
-
// Distribui descontos a nível de despesa proporcionalmente ao valor do item.
|
|
1548
|
-
// Despesa.Valor = total bruto; Despesa.ValorLiquido = líquido pago.
|
|
1549
|
-
// Fator = ValorLiquido / Valor (entre 0 e 1).
|
|
1550
|
-
let precoUnitarioReal = valorBruto;
|
|
1551
|
-
let totalReal = totalBruto;
|
|
1552
|
-
let descontoAplicado;
|
|
1553
|
-
let precoBrutoOut;
|
|
1554
|
-
if (despesa) {
|
|
1555
|
-
const despBruto = Number(despesa["Valor"] ?? 0);
|
|
1556
|
-
const despLiquido = Number(despesa["ValorLiquido"] ?? despBruto);
|
|
1557
|
-
if (despBruto > 0 && Math.abs(despBruto - despLiquido) > 0.01) {
|
|
1558
|
-
const fator = despLiquido / despBruto;
|
|
1559
|
-
totalReal = Math.round(totalBruto * fator * 100) / 100;
|
|
1560
|
-
precoUnitarioReal = qtd > 0 ? Math.round((totalReal / qtd) * 100) / 100 : valorBruto * fator;
|
|
1561
|
-
descontoAplicado = Math.round((totalBruto - totalReal) * 100) / 100;
|
|
1562
|
-
precoBrutoOut = valorBruto;
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1584
|
+
const calc = aplicarDescontoProporcional(it, despesa);
|
|
1565
1585
|
return {
|
|
1566
1586
|
data: data.slice(0, 10),
|
|
1567
1587
|
produto: nomeProd.trim(),
|
|
1568
1588
|
fornecedor: String(it["PessoaNome"] ?? despesa?.["PessoaNome"] ?? "").trim(),
|
|
1569
|
-
preco_unitario:
|
|
1570
|
-
quantidade:
|
|
1571
|
-
valor_total:
|
|
1572
|
-
preco_unitario_bruto:
|
|
1573
|
-
desconto_aplicado: descontoAplicado,
|
|
1589
|
+
preco_unitario: calc.precoUnitario,
|
|
1590
|
+
quantidade: Number(it["Quantidade"] ?? 0),
|
|
1591
|
+
valor_total: calc.valorTotal,
|
|
1592
|
+
preco_unitario_bruto: calc.precoUnitarioBruto,
|
|
1593
|
+
desconto_aplicado: calc.descontoAplicado,
|
|
1574
1594
|
moeda: it["MoedaNome"] ? String(it["MoedaNome"]) : undefined,
|
|
1575
1595
|
};
|
|
1576
1596
|
})
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
8
8
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
9
9
|
import * as client from "./client.js";
|
|
10
10
|
import { openLoginUI } from "./login-server.js";
|
|
11
|
-
const server = new Server({ name: "next-finance-mcp", version: "0.9.
|
|
11
|
+
const server = new Server({ name: "next-finance-mcp", version: "0.9.22" }, { capabilities: { tools: {} } });
|
|
12
12
|
// ── Ferramentas ─────────────────────────────────────────────────────────────
|
|
13
13
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
14
14
|
tools: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-finance-mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.22",
|
|
4
4
|
"mcpName": "io.github.paivapiovesan/next-finance",
|
|
5
5
|
"description": "MCP Server para o NEXT Finance (finance.net.br) — login via browser, listagem de carteiras, contas e lançamentos",
|
|
6
6
|
"type": "module",
|