erp-vidrio-templado-backend-v2/src/modules/mcp/tools/sales-tools.service.ts
Adrian Flores Cortes bc5a389edb [PROP-CORE-004] feat: Add Phase 6 modules from erp-core
Propagated modules:
- payment-terminals: MercadoPago + Clip TPV
- ai: Role-based AI access (ADMIN, SUPERVISOR_PRODUCCION, OPERADOR_CORTE, OPERADOR_HORNO)
- mcp: 18 ERP tools for AI assistants

Priority: P2 (industrial clients pay via transfer)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 02:45:48 -06:00

330 lines
9.5 KiB
TypeScript

import {
McpToolProvider,
McpToolDefinition,
McpToolHandler,
McpContext,
} from '../interfaces';
/**
* Sales Tools Service
* Provides MCP tools for sales management and reporting.
* Used by: ADMIN, SUPERVISOR, OPERATOR roles
*/
export class SalesToolsService implements McpToolProvider {
getTools(): McpToolDefinition[] {
return [
{
name: 'get_sales_summary',
description: 'Obtiene resumen de ventas del dia, semana o mes',
category: 'sales',
parameters: {
type: 'object',
properties: {
period: {
type: 'string',
enum: ['today', 'week', 'month', 'year'],
description: 'Periodo del resumen',
default: 'today',
},
branch_id: {
type: 'string',
format: 'uuid',
description: 'Filtrar por sucursal (opcional)',
},
},
},
returns: {
type: 'object',
properties: {
total_sales: { type: 'number' },
transaction_count: { type: 'number' },
average_ticket: { type: 'number' },
},
},
},
{
name: 'get_sales_report',
description: 'Genera reporte detallado de ventas por rango de fechas',
category: 'sales',
parameters: {
type: 'object',
properties: {
start_date: {
type: 'string',
format: 'date',
description: 'Fecha inicial (YYYY-MM-DD)',
},
end_date: {
type: 'string',
format: 'date',
description: 'Fecha final (YYYY-MM-DD)',
},
group_by: {
type: 'string',
enum: ['day', 'week', 'month', 'branch', 'category', 'seller'],
description: 'Agrupar resultados por',
default: 'day',
},
branch_id: {
type: 'string',
format: 'uuid',
description: 'Filtrar por sucursal',
},
},
required: ['start_date', 'end_date'],
},
returns: { type: 'array', items: { type: 'object' } },
},
{
name: 'get_top_products',
description: 'Obtiene los productos mas vendidos',
category: 'sales',
parameters: {
type: 'object',
properties: {
period: {
type: 'string',
enum: ['today', 'week', 'month', 'year'],
default: 'month',
},
limit: { type: 'number', default: 10 },
branch_id: { type: 'string', format: 'uuid' },
},
},
returns: { type: 'array', items: { type: 'object' } },
},
{
name: 'get_top_customers',
description: 'Obtiene los clientes con mas compras',
category: 'sales',
parameters: {
type: 'object',
properties: {
period: {
type: 'string',
enum: ['month', 'quarter', 'year'],
default: 'month',
},
limit: { type: 'number', default: 10 },
order_by: {
type: 'string',
enum: ['amount', 'transactions'],
default: 'amount',
},
},
},
returns: { type: 'array', items: { type: 'object' } },
},
{
name: 'get_sales_by_branch',
description: 'Compara ventas entre sucursales',
category: 'sales',
parameters: {
type: 'object',
properties: {
period: {
type: 'string',
enum: ['today', 'week', 'month'],
default: 'today',
},
},
},
returns: { type: 'array', items: { type: 'object' } },
},
{
name: 'get_my_sales',
description: 'Obtiene las ventas del usuario actual (operador)',
category: 'sales',
parameters: {
type: 'object',
properties: {
period: {
type: 'string',
enum: ['today', 'week', 'month'],
default: 'today',
},
},
},
returns: {
type: 'object',
properties: {
total: { type: 'number' },
count: { type: 'number' },
sales: { type: 'array' },
},
},
},
{
name: 'create_sale',
description: 'Registra una nueva venta',
category: 'sales',
parameters: {
type: 'object',
properties: {
items: {
type: 'array',
items: {
type: 'object',
properties: {
product_id: { type: 'string', format: 'uuid' },
quantity: { type: 'number', minimum: 1 },
unit_price: { type: 'number' },
discount: { type: 'number', default: 0 },
},
required: ['product_id', 'quantity'],
},
},
customer_id: { type: 'string', format: 'uuid' },
payment_method: {
type: 'string',
enum: ['cash', 'card', 'transfer', 'credit'],
},
notes: { type: 'string' },
},
required: ['items', 'payment_method'],
},
returns: {
type: 'object',
properties: {
sale_id: { type: 'string' },
total: { type: 'number' },
status: { type: 'string' },
},
},
},
];
}
getHandler(toolName: string): McpToolHandler | undefined {
const handlers: Record<string, McpToolHandler> = {
get_sales_summary: this.getSalesSummary.bind(this),
get_sales_report: this.getSalesReport.bind(this),
get_top_products: this.getTopProducts.bind(this),
get_top_customers: this.getTopCustomers.bind(this),
get_sales_by_branch: this.getSalesByBranch.bind(this),
get_my_sales: this.getMySales.bind(this),
create_sale: this.createSale.bind(this),
};
return handlers[toolName];
}
private async getSalesSummary(
params: { period?: string; branch_id?: string },
context: McpContext
): Promise<any> {
// TODO: Connect to SalesService
const period = params.period || 'today';
return {
period,
branch_id: params.branch_id || 'all',
total_sales: 15750.00,
transaction_count: 42,
average_ticket: 375.00,
comparison: {
previous_period: 14200.00,
change_percent: 10.9,
},
message: 'Conectar a SalesService real',
};
}
private async getSalesReport(
params: { start_date: string; end_date: string; group_by?: string; branch_id?: string },
context: McpContext
): Promise<any[]> {
// TODO: Connect to SalesService
return [
{
date: params.start_date,
total: 5250.00,
count: 15,
avg_ticket: 350.00,
},
{
date: params.end_date,
total: 4800.00,
count: 12,
avg_ticket: 400.00,
},
];
}
private async getTopProducts(
params: { period?: string; limit?: number; branch_id?: string },
context: McpContext
): Promise<any[]> {
// TODO: Connect to SalesService
return [
{ rank: 1, product: 'Producto A', quantity: 150, revenue: 7500.00 },
{ rank: 2, product: 'Producto B', quantity: 120, revenue: 6000.00 },
{ rank: 3, product: 'Producto C', quantity: 100, revenue: 5000.00 },
].slice(0, params.limit || 10);
}
private async getTopCustomers(
params: { period?: string; limit?: number; order_by?: string },
context: McpContext
): Promise<any[]> {
// TODO: Connect to CustomersService
return [
{ rank: 1, customer: 'Cliente A', total: 25000.00, transactions: 15 },
{ rank: 2, customer: 'Cliente B', total: 18000.00, transactions: 12 },
].slice(0, params.limit || 10);
}
private async getSalesByBranch(
params: { period?: string },
context: McpContext
): Promise<any[]> {
// TODO: Connect to SalesService + BranchesService
return [
{ branch: 'Sucursal Centro', total: 8500.00, count: 25 },
{ branch: 'Sucursal Norte', total: 7250.00, count: 17 },
];
}
private async getMySales(
params: { period?: string },
context: McpContext
): Promise<any> {
// TODO: Connect to SalesService with context.userId
return {
user_id: context.userId,
period: params.period || 'today',
total: 3500.00,
count: 8,
sales: [
{ id: 'sale-1', total: 450.00, time: '10:30' },
{ id: 'sale-2', total: 680.00, time: '11:45' },
],
};
}
private async createSale(
params: {
items: Array<{ product_id: string; quantity: number; unit_price?: number; discount?: number }>;
customer_id?: string;
payment_method: string;
notes?: string;
},
context: McpContext
): Promise<any> {
// TODO: Connect to SalesService
const total = params.items.reduce((sum, item) => {
const price = item.unit_price || 100; // Default price for demo
const discount = item.discount || 0;
return sum + (price * item.quantity * (1 - discount / 100));
}, 0);
return {
sale_id: `SALE-${Date.now()}`,
total,
items_count: params.items.length,
payment_method: params.payment_method,
status: 'completed',
created_by: context.userId,
message: 'Conectar a SalesService real',
};
}
}