"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); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OrdersService = void 0; const common_1 = require("@nestjs/common"); const typeorm_1 = require("@nestjs/typeorm"); const typeorm_2 = require("typeorm"); const order_entity_1 = require("./entities/order.entity"); const order_item_entity_1 = require("./entities/order-item.entity"); let OrdersService = class OrdersService { constructor(orderRepo, orderItemRepo) { this.orderRepo = orderRepo; this.orderItemRepo = orderItemRepo; } generateOrderNumber() { const now = new Date(); const dateStr = now.toISOString().slice(2, 10).replace(/-/g, ''); const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0'); return `P${dateStr}-${random}`; } async create(tenantId, dto) { let subtotal = 0; const items = dto.items.map((item) => { const itemSubtotal = item.quantity * item.unitPrice; subtotal += itemSubtotal; return { ...item, subtotal: itemSubtotal, }; }); const deliveryFee = dto.deliveryFee || 0; const discountAmount = dto.discountAmount || 0; const total = subtotal + deliveryFee - discountAmount; const order = this.orderRepo.create({ tenantId, orderNumber: this.generateOrderNumber(), customerId: dto.customerId, channel: dto.channel || order_entity_1.OrderChannel.WHATSAPP, orderType: dto.orderType, subtotal, deliveryFee, discountAmount, total, deliveryAddress: dto.deliveryAddress, deliveryNotes: dto.deliveryNotes, customerNotes: dto.customerNotes, paymentMethod: dto.paymentMethod, status: order_entity_1.OrderStatus.PENDING, items: items.map((item) => this.orderItemRepo.create(item)), }); return this.orderRepo.save(order); } async findAll(tenantId, status) { const where = { tenantId }; if (status) { where.status = status; } return this.orderRepo.find({ where, relations: ['items', 'customer'], order: { createdAt: 'DESC' }, }); } async findOne(tenantId, id) { const order = await this.orderRepo.findOne({ where: { id, tenantId }, relations: ['items', 'customer'], }); if (!order) { throw new common_1.NotFoundException('Pedido no encontrado'); } return order; } async findByOrderNumber(tenantId, orderNumber) { const order = await this.orderRepo.findOne({ where: { orderNumber, tenantId }, relations: ['items', 'customer'], }); if (!order) { throw new common_1.NotFoundException('Pedido no encontrado'); } return order; } async getActiveOrders(tenantId) { return this.orderRepo.find({ where: [ { tenantId, status: order_entity_1.OrderStatus.PENDING }, { tenantId, status: order_entity_1.OrderStatus.CONFIRMED }, { tenantId, status: order_entity_1.OrderStatus.PREPARING }, { tenantId, status: order_entity_1.OrderStatus.READY }, ], relations: ['items', 'customer'], order: { createdAt: 'ASC' }, }); } async getTodayOrders(tenantId) { const today = new Date(); today.setHours(0, 0, 0, 0); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); return this.orderRepo.find({ where: { tenantId, createdAt: (0, typeorm_2.Between)(today, tomorrow), }, relations: ['items', 'customer'], order: { createdAt: 'DESC' }, }); } async updateStatus(tenantId, id, dto) { const order = await this.findOne(tenantId, id); this.validateStatusTransition(order.status, dto.status); order.status = dto.status; const now = new Date(); switch (dto.status) { case order_entity_1.OrderStatus.CONFIRMED: order.confirmedAt = now; break; case order_entity_1.OrderStatus.PREPARING: order.preparingAt = now; break; case order_entity_1.OrderStatus.READY: order.readyAt = now; break; case order_entity_1.OrderStatus.COMPLETED: case order_entity_1.OrderStatus.DELIVERED: order.completedAt = now; break; case order_entity_1.OrderStatus.CANCELLED: order.cancelledAt = now; order.cancelledReason = dto.reason; break; } if (dto.internalNotes) { order.internalNotes = dto.internalNotes; } return this.orderRepo.save(order); } validateStatusTransition(currentStatus, newStatus) { const validTransitions = { [order_entity_1.OrderStatus.PENDING]: [order_entity_1.OrderStatus.CONFIRMED, order_entity_1.OrderStatus.CANCELLED], [order_entity_1.OrderStatus.CONFIRMED]: [order_entity_1.OrderStatus.PREPARING, order_entity_1.OrderStatus.CANCELLED], [order_entity_1.OrderStatus.PREPARING]: [order_entity_1.OrderStatus.READY, order_entity_1.OrderStatus.CANCELLED], [order_entity_1.OrderStatus.READY]: [order_entity_1.OrderStatus.DELIVERED, order_entity_1.OrderStatus.COMPLETED, order_entity_1.OrderStatus.CANCELLED], [order_entity_1.OrderStatus.DELIVERED]: [order_entity_1.OrderStatus.COMPLETED], [order_entity_1.OrderStatus.COMPLETED]: [], [order_entity_1.OrderStatus.CANCELLED]: [], }; if (!validTransitions[currentStatus].includes(newStatus)) { throw new common_1.BadRequestException(`No se puede cambiar de ${currentStatus} a ${newStatus}`); } } async getOrderStats(tenantId) { const today = new Date(); today.setHours(0, 0, 0, 0); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); const [todayOrders, pendingCount, preparingCount, readyCount,] = await Promise.all([ this.orderRepo.count({ where: { tenantId, createdAt: (0, typeorm_2.Between)(today, tomorrow) }, }), this.orderRepo.count({ where: { tenantId, status: order_entity_1.OrderStatus.PENDING } }), this.orderRepo.count({ where: { tenantId, status: order_entity_1.OrderStatus.PREPARING } }), this.orderRepo.count({ where: { tenantId, status: order_entity_1.OrderStatus.READY } }), ]); const todaySales = await this.orderRepo .createQueryBuilder('order') .select('SUM(order.total)', 'total') .where('order.tenant_id = :tenantId', { tenantId }) .andWhere('order.created_at >= :today', { today }) .andWhere('order.created_at < :tomorrow', { tomorrow }) .andWhere('order.status NOT IN (:...statuses)', { statuses: [order_entity_1.OrderStatus.CANCELLED], }) .getRawOne(); return { todayOrders, todaySales: Number(todaySales?.total) || 0, pending: pendingCount, preparing: preparingCount, ready: readyCount, activeTotal: pendingCount + preparingCount + readyCount, }; } }; exports.OrdersService = OrdersService; exports.OrdersService = OrdersService = __decorate([ (0, common_1.Injectable)(), __param(0, (0, typeorm_1.InjectRepository)(order_entity_1.Order)), __param(1, (0, typeorm_1.InjectRepository)(order_item_entity_1.OrderItem)), __metadata("design:paramtypes", [typeorm_2.Repository, typeorm_2.Repository]) ], OrdersService); //# sourceMappingURL=orders.service.js.map