- Prefijo v2: MCH - TRACEABILITY-MASTER.yml creado - Listo para integracion como submodulo Workspace: v2.0.0 | SIMCO: v4.0.0
140 lines
5.6 KiB
JavaScript
140 lines
5.6 KiB
JavaScript
"use strict";
|
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.WidgetsService = void 0;
|
|
const common_1 = require("@nestjs/common");
|
|
const typeorm_1 = require("typeorm");
|
|
let WidgetsService = class WidgetsService {
|
|
constructor(dataSource) {
|
|
this.dataSource = dataSource;
|
|
}
|
|
async getSummary(tenantId) {
|
|
const today = new Date().toISOString().split('T')[0];
|
|
const salesResult = await this.dataSource.query(`SELECT
|
|
COALESCE(SUM(total), 0) as total,
|
|
COUNT(*) as count
|
|
FROM sales.sales
|
|
WHERE tenant_id = $1
|
|
AND DATE(created_at) = $2
|
|
AND status = 'completed'`, [tenantId, today]);
|
|
const ordersResult = await this.dataSource.query(`SELECT COUNT(*) as count
|
|
FROM orders.orders
|
|
WHERE tenant_id = $1
|
|
AND status IN ('pending', 'confirmed', 'preparing')`, [tenantId]);
|
|
const stockResult = await this.dataSource.query(`SELECT COUNT(*) as count
|
|
FROM catalog.products
|
|
WHERE tenant_id = $1
|
|
AND stock <= min_stock
|
|
AND status = 'active'`, [tenantId]);
|
|
const creditsResult = await this.dataSource.query(`SELECT COUNT(DISTINCT customer_id) as count
|
|
FROM customers.customer_credits
|
|
WHERE tenant_id = $1
|
|
AND status = 'active'
|
|
AND balance > 0`, [tenantId]);
|
|
return {
|
|
salesToday: parseFloat(salesResult[0]?.total || '0'),
|
|
transactionsCount: parseInt(salesResult[0]?.count || '0'),
|
|
pendingOrders: parseInt(ordersResult[0]?.count || '0'),
|
|
lowStockCount: parseInt(stockResult[0]?.count || '0'),
|
|
pendingCredits: parseInt(creditsResult[0]?.count || '0'),
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
}
|
|
async getAlerts(tenantId) {
|
|
const alerts = [];
|
|
const lowStock = await this.dataSource.query(`SELECT name, stock, min_stock
|
|
FROM catalog.products
|
|
WHERE tenant_id = $1
|
|
AND stock <= min_stock
|
|
AND status = 'active'
|
|
ORDER BY stock ASC
|
|
LIMIT 5`, [tenantId]);
|
|
if (lowStock.length > 0) {
|
|
alerts.push({
|
|
type: 'low_stock',
|
|
title: 'Stock bajo',
|
|
message: lowStock.length === 1
|
|
? `${lowStock[0].name}: ${lowStock[0].stock} unidades`
|
|
: `${lowStock.length} productos con stock bajo`,
|
|
count: lowStock.length,
|
|
priority: lowStock.some((p) => p.stock === 0) ? 'high' : 'medium',
|
|
});
|
|
}
|
|
const pendingOrders = await this.dataSource.query(`SELECT COUNT(*) as count
|
|
FROM orders.orders
|
|
WHERE tenant_id = $1
|
|
AND status = 'pending'`, [tenantId]);
|
|
if (parseInt(pendingOrders[0]?.count || '0') > 0) {
|
|
const count = parseInt(pendingOrders[0].count);
|
|
alerts.push({
|
|
type: 'pending_order',
|
|
title: 'Pedidos pendientes',
|
|
message: count === 1
|
|
? '1 pedido por confirmar'
|
|
: `${count} pedidos por confirmar`,
|
|
count,
|
|
priority: count > 3 ? 'high' : 'medium',
|
|
});
|
|
}
|
|
const overdueCredits = await this.dataSource.query(`SELECT COUNT(DISTINCT cc.customer_id) as count
|
|
FROM customers.customer_credits cc
|
|
WHERE cc.tenant_id = $1
|
|
AND cc.status = 'active'
|
|
AND cc.due_date < CURRENT_DATE`, [tenantId]);
|
|
if (parseInt(overdueCredits[0]?.count || '0') > 0) {
|
|
const count = parseInt(overdueCredits[0].count);
|
|
alerts.push({
|
|
type: 'overdue_credit',
|
|
title: 'Fiados vencidos',
|
|
message: count === 1
|
|
? '1 cliente con fiado vencido'
|
|
: `${count} clientes con fiado vencido`,
|
|
count,
|
|
priority: 'high',
|
|
});
|
|
}
|
|
return alerts;
|
|
}
|
|
getQuickActions() {
|
|
return [
|
|
{
|
|
id: 'new_sale',
|
|
title: 'Nueva Venta',
|
|
icon: 'cart',
|
|
deepLink: 'michangarrito://pos/new',
|
|
},
|
|
{
|
|
id: 'scan_product',
|
|
title: 'Escanear Producto',
|
|
icon: 'barcode',
|
|
deepLink: 'michangarrito://scan',
|
|
},
|
|
{
|
|
id: 'view_orders',
|
|
title: 'Ver Pedidos',
|
|
icon: 'clipboard',
|
|
deepLink: 'michangarrito://orders',
|
|
},
|
|
{
|
|
id: 'view_inventory',
|
|
title: 'Ver Inventario',
|
|
icon: 'box',
|
|
deepLink: 'michangarrito://inventory',
|
|
},
|
|
];
|
|
}
|
|
};
|
|
exports.WidgetsService = WidgetsService;
|
|
exports.WidgetsService = WidgetsService = __decorate([
|
|
(0, common_1.Injectable)(),
|
|
__metadata("design:paramtypes", [typeorm_1.DataSource])
|
|
], WidgetsService);
|
|
//# sourceMappingURL=widgets.service.js.map
|