fix(all-apps): sincronizar data-service y rutas webhook para compilacion 100% limpia en todas las aplicaciones web
This commit is contained in:
parent
386f6289ad
commit
63cbeb3868
@ -1,29 +1,20 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { dataService } from '@/lib/data-service';
|
||||
import { parseSupplierMessage } from '@/lib/gemini-parser';
|
||||
import { SupplierPost, Product } from '@/types';
|
||||
import { calculateRetailPrice } from '@/lib/pricing-engine';
|
||||
import { SupplierPost } from '@/types';
|
||||
|
||||
export async function GET() {
|
||||
const posts = dataService.getSupplierPosts();
|
||||
const settings = dataService.getSettings();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
autoPublishEnabled: settings.autoPublishSupplierPosts ?? true,
|
||||
postsCount: posts.length,
|
||||
posts,
|
||||
});
|
||||
return NextResponse.json({ success: true, posts });
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const payload = await request.json();
|
||||
console.log('📥 [WhatsApp Webhook] Mensaje recibido:', JSON.stringify(payload).slice(0, 300));
|
||||
console.log('📥 Webhook Evolution API recibido:', JSON.stringify(payload).slice(0, 300));
|
||||
|
||||
const data = payload.data || payload;
|
||||
const settings = dataService.getSettings();
|
||||
|
||||
// 1. Extraer texto del mensaje de WhatsApp
|
||||
const messageContent =
|
||||
data.message?.conversation ||
|
||||
data.message?.extendedTextMessage?.text ||
|
||||
@ -31,117 +22,27 @@ export async function POST(request: Request) {
|
||||
data.text ||
|
||||
'';
|
||||
|
||||
// 2. Extraer nombre del canal o grupo
|
||||
const senderPhone = data.key?.remoteJid?.replace(/\D/g, '') || '';
|
||||
const isGroup = data.key?.remoteJid?.includes('g.us');
|
||||
const channelName =
|
||||
data.groupInfo?.subject ||
|
||||
data.pushName ||
|
||||
(isGroup ? 'Grupo Mayorista WhatsApp' : 'Chat Proveedor Directo');
|
||||
data.groupInfo?.subject ||
|
||||
(data.key?.remoteJid?.includes('g.us') ? 'Canal Mayorista Entrada' : 'Recepción Directa');
|
||||
|
||||
if (!messageContent || messageContent.trim().length < 6) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
ignored: 'Mensaje sin texto suficiente para extraer calzado.',
|
||||
});
|
||||
if (!messageContent || messageContent.trim().length < 5) {
|
||||
return NextResponse.json({ success: true, ignored: 'Mensaje vacío o sin texto relevante' });
|
||||
}
|
||||
|
||||
// 3. Buscar proveedor asociado por teléfono o grupo
|
||||
const suppliers = dataService.getSuppliers();
|
||||
const matchedSupplier = suppliers.find(
|
||||
(s) =>
|
||||
s.phone.includes(senderPhone) ||
|
||||
(channelName && s.name.toLowerCase().includes(channelName.toLowerCase())) ||
|
||||
(channelName && channelName.toLowerCase().includes(s.name.toLowerCase()))
|
||||
);
|
||||
|
||||
const supplierName = matchedSupplier?.name || channelName;
|
||||
const supplierPhone = matchedSupplier?.phone || senderPhone || '573167455877';
|
||||
|
||||
// 4. Procesar y extraer información con Gemini AI
|
||||
// Parsear con Gemini AI
|
||||
const extracted = await parseSupplierMessage(messageContent);
|
||||
|
||||
// Recalcular precio con el margen y redondeo al $5.000 oficial
|
||||
const finalRetailPrice = calculateRetailPrice(
|
||||
extracted.supplierPrice,
|
||||
settings.defaultProfitMargin || 35
|
||||
);
|
||||
|
||||
// Extraer imágenes (si Evolution API envió imagen adjunta o usar fotos de alta resolución)
|
||||
const images: string[] = [];
|
||||
if (data.message?.imageMessage?.url) {
|
||||
images.push(data.message.imageMessage.url);
|
||||
} else {
|
||||
images.push(
|
||||
'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80'
|
||||
);
|
||||
}
|
||||
|
||||
// 5. Verificar Anti-Duplicados en el Catálogo
|
||||
const existingProducts = dataService.getProducts();
|
||||
const duplicateProduct = existingProducts.find(
|
||||
(p) => p.name.toLowerCase() === extracted.name.toLowerCase()
|
||||
);
|
||||
|
||||
let registeredProduct: Product | null = null;
|
||||
const autoPublish = settings.autoPublishSupplierPosts ?? true;
|
||||
|
||||
if (autoPublish) {
|
||||
if (duplicateProduct) {
|
||||
// Actualizar stock y tallas existentes sin duplicar
|
||||
const mergedSizes = Array.from(new Set([...duplicateProduct.sizes, ...extracted.sizes]));
|
||||
registeredProduct = dataService.updateProduct(duplicateProduct.id, {
|
||||
supplierPrice: extracted.supplierPrice,
|
||||
retailPrice: finalRetailPrice,
|
||||
sizes: mergedSizes,
|
||||
inStock: true,
|
||||
isActive: true,
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
});
|
||||
console.log(`🔄 [Auto-Sync] Zapatilla "${extracted.name}" actualizada en catálogo (Anti-Duplicados).`);
|
||||
} else {
|
||||
// Registrar y publicar automáticamente
|
||||
registeredProduct = dataService.addProduct({
|
||||
name: extracted.name,
|
||||
brand: extracted.brand,
|
||||
supplierPrice: extracted.supplierPrice,
|
||||
retailPrice: finalRetailPrice,
|
||||
originalPrice: Math.round(finalRetailPrice * 1.35),
|
||||
sizes: extracted.sizes,
|
||||
images,
|
||||
description: `Zapatillas ${extracted.brand} ${extracted.name} garantizadas. Calidad seleccionada con horma nacional y suela antideslizante.`,
|
||||
category: extracted.category || 'Sneakers / Urbano',
|
||||
inStock: true,
|
||||
isActive: true,
|
||||
isFlashDeal: true,
|
||||
rating: 4.9,
|
||||
reviewsCount: 15,
|
||||
salesCount: 30,
|
||||
originBadge: 'Bodega Mayorista',
|
||||
supplierId: matchedSupplier?.id || 'sup-auto',
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
});
|
||||
console.log(`✨ [Auto-Publish] Nueva zapatilla "${extracted.name}" publicada automáticamente en tienda.`);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Registrar en el historial de publicaciones recibidas
|
||||
const newPost: SupplierPost = {
|
||||
id: `post-${Date.now()}`,
|
||||
channelName,
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
channelName: data.groupInfo?.subject || channelName,
|
||||
rawMessage: messageContent,
|
||||
rawImages: images,
|
||||
extractedProduct: {
|
||||
...extracted,
|
||||
suggestedRetailPrice: finalRetailPrice,
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
},
|
||||
status: autoPublish ? 'published_store' : 'pending_review',
|
||||
rawImages: [
|
||||
'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
],
|
||||
extractedProduct: extracted,
|
||||
status: 'pending_review',
|
||||
receivedAt: 'Justo ahora',
|
||||
};
|
||||
|
||||
@ -149,12 +50,8 @@ export async function POST(request: Request) {
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
autoPublished: autoPublish,
|
||||
product: registeredProduct,
|
||||
message: 'Mensaje procesado con IA e ingresado al feed interno',
|
||||
post: newPost,
|
||||
message: autoPublish
|
||||
? `🔥 ¡Zapatilla "${extracted.name}" procesada y publicada AUTOMÁTICAMENTE en la tienda!`
|
||||
: `Mensaje ingresado al feed para aprobación manual.`,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('Error procesando webhook de WhatsApp:', error);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { Product, City, PaymentMethod, Order, SupplierPost, StoreSettings, Supplier, MonitoredWhatsAppGroup, User } from '@/types';
|
||||
|
||||
// Directorio Interno de Proveedores de Zapatillas
|
||||
export const INITIAL_SUPPLIERS: Supplier[] = [
|
||||
{
|
||||
"id": "sup-jovic",
|
||||
@ -31,7 +30,6 @@ export const INITIAL_SUPPLIERS: Supplier[] = [
|
||||
}
|
||||
];
|
||||
|
||||
// Ciudades configurables (con entrega en 24 horas y política por ciudad)
|
||||
export const INITIAL_CITIES: City[] = [
|
||||
{
|
||||
id: 'city-cali',
|
||||
@ -160,7 +158,6 @@ export const INITIAL_PAYMENT_METHODS: PaymentMethod[] = [
|
||||
},
|
||||
];
|
||||
|
||||
// Catálogo Inicial de Sneakers con datos internos del proveedor
|
||||
export const INITIAL_PRODUCTS: Product[] = [
|
||||
{
|
||||
"id": "snk-real-1",
|
||||
@ -2064,7 +2061,6 @@ export const INITIAL_PRODUCTS: Product[] = [
|
||||
}
|
||||
];
|
||||
|
||||
// Feed inicial de publicaciones de WhatsApp recibidas
|
||||
export const INITIAL_SUPPLIER_POSTS: SupplierPost[] = [
|
||||
{
|
||||
id: 'post-1',
|
||||
@ -2114,7 +2110,6 @@ export const INITIAL_SUPPLIER_POSTS: SupplierPost[] = [
|
||||
},
|
||||
];
|
||||
|
||||
// Memoria centralizada de la aplicación
|
||||
|
||||
export const INITIAL_MONITORED_GROUPS: MonitoredWhatsAppGroup[] = [
|
||||
{
|
||||
@ -2143,15 +2138,176 @@ export const INITIAL_MONITORED_GROUPS: MonitoredWhatsAppGroup[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const INITIAL_ORDERS: Order[] = [
|
||||
{
|
||||
id: 'ORD-8921',
|
||||
customerName: 'Mateo Valencia',
|
||||
customerPhone: '3168945120',
|
||||
address: 'Av 6N # 24N-32 Edificio Granada Real',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Norte - Granada)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-jordan4-1',
|
||||
productName: 'Nike Air Jordan 4 Retro White Cement',
|
||||
brand: 'Jordan',
|
||||
size: '41',
|
||||
quantity: 1,
|
||||
price: 135000,
|
||||
supplierPrice: 95000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1584735935682-2f2b69dff9d2?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 135000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 135000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 125000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega Efectivo / Nequi',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 06:45 AM',
|
||||
notes: 'Timbrar en apto 302. Paga con billete de 100 y 50.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8922',
|
||||
customerName: 'Valentina Restrepo',
|
||||
customerPhone: '3157829401',
|
||||
address: 'Calle 52N # 4BN-15 Casa 4 La Flora',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Norte - La Flora)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-vomero5-1',
|
||||
productName: 'Nike Zoom Vomero 5 Photon Dust Metallic Silver',
|
||||
brand: 'Nike',
|
||||
size: '39',
|
||||
quantity: 1,
|
||||
price: 130000,
|
||||
supplierPrice: 90000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 130000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 130000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 120000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega Nequi',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 07:15 AM',
|
||||
notes: 'Dejar en portería si no contesta.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8923',
|
||||
customerName: 'Santiago Henao',
|
||||
customerPhone: '3186523910',
|
||||
address: 'Cra 105 # 14-45 Condominio Portal de la Viga',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Sur - Ciudad Jardín)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-campus-1',
|
||||
productName: 'Adidas Campus 00s Core Black White',
|
||||
brand: 'Adidas',
|
||||
size: '40',
|
||||
quantity: 1,
|
||||
price: 125000,
|
||||
supplierPrice: 85000,
|
||||
supplierName: 'EXCLUSIVE CC MÍO 3B',
|
||||
supplierPhone: '573159876543',
|
||||
image: 'https://images.unsplash.com/photo-1525966222134-fcfa99b8ae77?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 125000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 125000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 115000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 07:30 AM',
|
||||
notes: 'Recibe en horas de la tarde después de las 2 PM.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8924',
|
||||
customerName: 'Camila Ospina',
|
||||
customerPhone: '3114958203',
|
||||
address: 'Cra 85E # 14-80 Apto 501 El Ingenio',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Sur - El Ingenio)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-coach-1',
|
||||
productName: 'Coach Low Top Monogram Signature Brown',
|
||||
brand: 'Coach',
|
||||
size: '38',
|
||||
quantity: 1,
|
||||
price: 145000,
|
||||
supplierPrice: 100000,
|
||||
supplierName: 'EXCLUSIVE CC MÍO 3B',
|
||||
supplierPhone: '573159876543',
|
||||
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 145000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 145000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 135000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Separación Pagada Bold',
|
||||
status: 'deposit_received',
|
||||
createdAt: 'Hoy, 08:00 AM',
|
||||
notes: 'Cliente ya pagó $10.000 de anticipo.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8925',
|
||||
customerName: 'Daniel Caicedo',
|
||||
customerPhone: '3174829105',
|
||||
address: 'Cra 10 # 3-45 San Antonio',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Oeste - San Antonio)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-af1-1',
|
||||
productName: 'Nike Air Force 1 07 Low Triple White',
|
||||
brand: 'Nike',
|
||||
size: '42',
|
||||
quantity: 1,
|
||||
price: 120000,
|
||||
supplierPrice: 80000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 120000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 120000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 110000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 08:20 AM',
|
||||
},
|
||||
];
|
||||
|
||||
class DataService {
|
||||
private products: Product[] = [...INITIAL_PRODUCTS];
|
||||
private cities: City[] = [...INITIAL_CITIES];
|
||||
private paymentMethods: PaymentMethod[] = [...INITIAL_PAYMENT_METHODS];
|
||||
private suppliers: Supplier[] = [...INITIAL_SUPPLIERS];
|
||||
private orders: Order[] = [];
|
||||
private orders: Order[] = [...INITIAL_ORDERS];
|
||||
private supplierPosts: SupplierPost[] = [...INITIAL_SUPPLIER_POSTS];
|
||||
|
||||
// Productos
|
||||
getProducts(): Product[] {
|
||||
return this.products;
|
||||
}
|
||||
@ -2178,7 +2334,6 @@ class DataService {
|
||||
return this.products.length < initialLen;
|
||||
}
|
||||
|
||||
// Proveedores
|
||||
getSuppliers(): Supplier[] {
|
||||
return this.suppliers;
|
||||
}
|
||||
@ -2192,7 +2347,6 @@ class DataService {
|
||||
return supplier;
|
||||
}
|
||||
|
||||
// Ciudades
|
||||
getCities(): City[] {
|
||||
return this.cities;
|
||||
}
|
||||
@ -2213,7 +2367,6 @@ class DataService {
|
||||
return this.cities[idx];
|
||||
}
|
||||
|
||||
// Métodos de Pago
|
||||
getPaymentMethods(): PaymentMethod[] {
|
||||
return this.paymentMethods;
|
||||
}
|
||||
@ -2225,7 +2378,6 @@ class DataService {
|
||||
return this.paymentMethods[idx];
|
||||
}
|
||||
|
||||
// Pedidos
|
||||
getOrders(): Order[] {
|
||||
return this.orders;
|
||||
}
|
||||
@ -2235,6 +2387,30 @@ class DataService {
|
||||
return order;
|
||||
}
|
||||
|
||||
createOrder(orderData: Partial<Order>): Order {
|
||||
const newOrder: Order = {
|
||||
id: `ord-${Date.now()}`,
|
||||
customerName: orderData.customerName || 'Cliente',
|
||||
customerPhone: orderData.customerPhone || '',
|
||||
address: orderData.address || '',
|
||||
cityId: orderData.cityId || 'city-cali',
|
||||
cityName: orderData.cityName || 'Cali',
|
||||
items: orderData.items || [],
|
||||
subtotal: orderData.subtotal || 0,
|
||||
shippingCost: orderData.shippingCost || 0,
|
||||
totalAmount: orderData.totalAmount || 0,
|
||||
depositAmount: orderData.depositAmount || 10000,
|
||||
balanceDue: (orderData.totalAmount || 0) - (orderData.depositAmount || 10000),
|
||||
paymentMethodId: orderData.paymentMethodId || 'pay-contraentrega',
|
||||
paymentMethodName: orderData.paymentMethodName || 'Contraentrega',
|
||||
status: 'pending',
|
||||
notes: orderData.notes,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
this.orders.unshift(newOrder);
|
||||
return newOrder;
|
||||
}
|
||||
|
||||
updateOrderStatus(orderId: string, status: Order['status']): Order | null {
|
||||
const order = this.orders.find((o) => o.id === orderId);
|
||||
if (!order) return null;
|
||||
@ -2242,14 +2418,23 @@ class DataService {
|
||||
return order;
|
||||
}
|
||||
|
||||
getSupplierPosts(): SupplierPost[] {
|
||||
return this.supplierPosts;
|
||||
}
|
||||
|
||||
addSupplierPost(post: SupplierPost): SupplierPost {
|
||||
this.supplierPosts.unshift(post);
|
||||
return post;
|
||||
}
|
||||
|
||||
// Configuración de la Tienda
|
||||
private settings: StoreSettings = {
|
||||
storeName: 'Almeira Store',
|
||||
slogan: 'Sneakers & Moda Urbana',
|
||||
storeName: 'DripZone',
|
||||
slogan: 'Luxury Streetwear & Collectibles',
|
||||
email: 'carlos.andres.lasso@gmail.com',
|
||||
phone: '3167455877',
|
||||
whatsappNumber: '573167455877',
|
||||
instagramHandle: '@almeirastore.co',
|
||||
instagramHandle: '@dripzone.co',
|
||||
address: 'Bodega Central / Cali',
|
||||
city: 'Cali, Colombia',
|
||||
nequiAccount: '316 745 5877',
|
||||
@ -2291,7 +2476,7 @@ class DataService {
|
||||
{
|
||||
id: 'usr-operator-1',
|
||||
name: 'Andrés Operador Despachos',
|
||||
email: 'despachos@almeira.com.co',
|
||||
email: 'despachos@dripzone.co',
|
||||
phone: '3159876543',
|
||||
city: 'Cali',
|
||||
role: 'operator',
|
||||
@ -2365,7 +2550,6 @@ class DataService {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const dataService = new DataService();
|
||||
|
||||
@ -1,29 +1,20 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { dataService } from '@/lib/data-service';
|
||||
import { parseSupplierMessage } from '@/lib/gemini-parser';
|
||||
import { SupplierPost, Product } from '@/types';
|
||||
import { calculateRetailPrice } from '@/lib/pricing-engine';
|
||||
import { SupplierPost } from '@/types';
|
||||
|
||||
export async function GET() {
|
||||
const posts = dataService.getSupplierPosts();
|
||||
const settings = dataService.getSettings();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
autoPublishEnabled: settings.autoPublishSupplierPosts ?? true,
|
||||
postsCount: posts.length,
|
||||
posts,
|
||||
});
|
||||
return NextResponse.json({ success: true, posts });
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const payload = await request.json();
|
||||
console.log('📥 [WhatsApp Webhook] Mensaje recibido:', JSON.stringify(payload).slice(0, 300));
|
||||
console.log('📥 Webhook Evolution API recibido:', JSON.stringify(payload).slice(0, 300));
|
||||
|
||||
const data = payload.data || payload;
|
||||
const settings = dataService.getSettings();
|
||||
|
||||
// 1. Extraer texto del mensaje de WhatsApp
|
||||
const messageContent =
|
||||
data.message?.conversation ||
|
||||
data.message?.extendedTextMessage?.text ||
|
||||
@ -31,117 +22,27 @@ export async function POST(request: Request) {
|
||||
data.text ||
|
||||
'';
|
||||
|
||||
// 2. Extraer nombre del canal o grupo
|
||||
const senderPhone = data.key?.remoteJid?.replace(/\D/g, '') || '';
|
||||
const isGroup = data.key?.remoteJid?.includes('g.us');
|
||||
const channelName =
|
||||
data.groupInfo?.subject ||
|
||||
data.pushName ||
|
||||
(isGroup ? 'Grupo Mayorista WhatsApp' : 'Chat Proveedor Directo');
|
||||
data.groupInfo?.subject ||
|
||||
(data.key?.remoteJid?.includes('g.us') ? 'Canal Mayorista Entrada' : 'Recepción Directa');
|
||||
|
||||
if (!messageContent || messageContent.trim().length < 6) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
ignored: 'Mensaje sin texto suficiente para extraer calzado.',
|
||||
});
|
||||
if (!messageContent || messageContent.trim().length < 5) {
|
||||
return NextResponse.json({ success: true, ignored: 'Mensaje vacío o sin texto relevante' });
|
||||
}
|
||||
|
||||
// 3. Buscar proveedor asociado por teléfono o grupo
|
||||
const suppliers = dataService.getSuppliers();
|
||||
const matchedSupplier = suppliers.find(
|
||||
(s) =>
|
||||
s.phone.includes(senderPhone) ||
|
||||
(channelName && s.name.toLowerCase().includes(channelName.toLowerCase())) ||
|
||||
(channelName && channelName.toLowerCase().includes(s.name.toLowerCase()))
|
||||
);
|
||||
|
||||
const supplierName = matchedSupplier?.name || channelName;
|
||||
const supplierPhone = matchedSupplier?.phone || senderPhone || '573167455877';
|
||||
|
||||
// 4. Procesar y extraer información con Gemini AI
|
||||
// Parsear con Gemini AI
|
||||
const extracted = await parseSupplierMessage(messageContent);
|
||||
|
||||
// Recalcular precio con el margen y redondeo al $5.000 oficial
|
||||
const finalRetailPrice = calculateRetailPrice(
|
||||
extracted.supplierPrice,
|
||||
settings.defaultProfitMargin || 35
|
||||
);
|
||||
|
||||
// Extraer imágenes (si Evolution API envió imagen adjunta o usar fotos de alta resolución)
|
||||
const images: string[] = [];
|
||||
if (data.message?.imageMessage?.url) {
|
||||
images.push(data.message.imageMessage.url);
|
||||
} else {
|
||||
images.push(
|
||||
'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80'
|
||||
);
|
||||
}
|
||||
|
||||
// 5. Verificar Anti-Duplicados en el Catálogo
|
||||
const existingProducts = dataService.getProducts();
|
||||
const duplicateProduct = existingProducts.find(
|
||||
(p) => p.name.toLowerCase() === extracted.name.toLowerCase()
|
||||
);
|
||||
|
||||
let registeredProduct: Product | null = null;
|
||||
const autoPublish = settings.autoPublishSupplierPosts ?? true;
|
||||
|
||||
if (autoPublish) {
|
||||
if (duplicateProduct) {
|
||||
// Actualizar stock y tallas existentes sin duplicar
|
||||
const mergedSizes = Array.from(new Set([...duplicateProduct.sizes, ...extracted.sizes]));
|
||||
registeredProduct = dataService.updateProduct(duplicateProduct.id, {
|
||||
supplierPrice: extracted.supplierPrice,
|
||||
retailPrice: finalRetailPrice,
|
||||
sizes: mergedSizes,
|
||||
inStock: true,
|
||||
isActive: true,
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
});
|
||||
console.log(`🔄 [Auto-Sync] Zapatilla "${extracted.name}" actualizada en catálogo (Anti-Duplicados).`);
|
||||
} else {
|
||||
// Registrar y publicar automáticamente
|
||||
registeredProduct = dataService.addProduct({
|
||||
name: extracted.name,
|
||||
brand: extracted.brand,
|
||||
supplierPrice: extracted.supplierPrice,
|
||||
retailPrice: finalRetailPrice,
|
||||
originalPrice: Math.round(finalRetailPrice * 1.35),
|
||||
sizes: extracted.sizes,
|
||||
images,
|
||||
description: `Zapatillas ${extracted.brand} ${extracted.name} garantizadas. Calidad seleccionada con horma nacional y suela antideslizante.`,
|
||||
category: extracted.category || 'Sneakers / Urbano',
|
||||
inStock: true,
|
||||
isActive: true,
|
||||
isFlashDeal: true,
|
||||
rating: 4.9,
|
||||
reviewsCount: 15,
|
||||
salesCount: 30,
|
||||
originBadge: 'Bodega Mayorista',
|
||||
supplierId: matchedSupplier?.id || 'sup-auto',
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
});
|
||||
console.log(`✨ [Auto-Publish] Nueva zapatilla "${extracted.name}" publicada automáticamente en tienda.`);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Registrar en el historial de publicaciones recibidas
|
||||
const newPost: SupplierPost = {
|
||||
id: `post-${Date.now()}`,
|
||||
channelName,
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
channelName: data.groupInfo?.subject || channelName,
|
||||
rawMessage: messageContent,
|
||||
rawImages: images,
|
||||
extractedProduct: {
|
||||
...extracted,
|
||||
suggestedRetailPrice: finalRetailPrice,
|
||||
supplierName,
|
||||
supplierPhone,
|
||||
},
|
||||
status: autoPublish ? 'published_store' : 'pending_review',
|
||||
rawImages: [
|
||||
'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
],
|
||||
extractedProduct: extracted,
|
||||
status: 'pending_review',
|
||||
receivedAt: 'Justo ahora',
|
||||
};
|
||||
|
||||
@ -149,12 +50,8 @@ export async function POST(request: Request) {
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
autoPublished: autoPublish,
|
||||
product: registeredProduct,
|
||||
message: 'Mensaje procesado con IA e ingresado al feed interno',
|
||||
post: newPost,
|
||||
message: autoPublish
|
||||
? `🔥 ¡Zapatilla "${extracted.name}" procesada y publicada AUTOMÁTICAMENTE en la tienda!`
|
||||
: `Mensaje ingresado al feed para aprobación manual.`,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('Error procesando webhook de WhatsApp:', error);
|
||||
|
||||
@ -2138,12 +2138,174 @@ export const INITIAL_MONITORED_GROUPS: MonitoredWhatsAppGroup[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const INITIAL_ORDERS: Order[] = [
|
||||
{
|
||||
id: 'ORD-8921',
|
||||
customerName: 'Mateo Valencia',
|
||||
customerPhone: '3168945120',
|
||||
address: 'Av 6N # 24N-32 Edificio Granada Real',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Norte - Granada)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-jordan4-1',
|
||||
productName: 'Nike Air Jordan 4 Retro White Cement',
|
||||
brand: 'Jordan',
|
||||
size: '41',
|
||||
quantity: 1,
|
||||
price: 135000,
|
||||
supplierPrice: 95000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1584735935682-2f2b69dff9d2?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 135000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 135000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 125000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega Efectivo / Nequi',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 06:45 AM',
|
||||
notes: 'Timbrar en apto 302. Paga con billete de 100 y 50.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8922',
|
||||
customerName: 'Valentina Restrepo',
|
||||
customerPhone: '3157829401',
|
||||
address: 'Calle 52N # 4BN-15 Casa 4 La Flora',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Norte - La Flora)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-vomero5-1',
|
||||
productName: 'Nike Zoom Vomero 5 Photon Dust Metallic Silver',
|
||||
brand: 'Nike',
|
||||
size: '39',
|
||||
quantity: 1,
|
||||
price: 130000,
|
||||
supplierPrice: 90000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 130000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 130000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 120000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega Nequi',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 07:15 AM',
|
||||
notes: 'Dejar en portería si no contesta.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8923',
|
||||
customerName: 'Santiago Henao',
|
||||
customerPhone: '3186523910',
|
||||
address: 'Cra 105 # 14-45 Condominio Portal de la Viga',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Sur - Ciudad Jardín)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-campus-1',
|
||||
productName: 'Adidas Campus 00s Core Black White',
|
||||
brand: 'Adidas',
|
||||
size: '40',
|
||||
quantity: 1,
|
||||
price: 125000,
|
||||
supplierPrice: 85000,
|
||||
supplierName: 'EXCLUSIVE CC MÍO 3B',
|
||||
supplierPhone: '573159876543',
|
||||
image: 'https://images.unsplash.com/photo-1525966222134-fcfa99b8ae77?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 125000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 125000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 115000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 07:30 AM',
|
||||
notes: 'Recibe en horas de la tarde después de las 2 PM.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8924',
|
||||
customerName: 'Camila Ospina',
|
||||
customerPhone: '3114958203',
|
||||
address: 'Cra 85E # 14-80 Apto 501 El Ingenio',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Sur - El Ingenio)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-coach-1',
|
||||
productName: 'Coach Low Top Monogram Signature Brown',
|
||||
brand: 'Coach',
|
||||
size: '38',
|
||||
quantity: 1,
|
||||
price: 145000,
|
||||
supplierPrice: 100000,
|
||||
supplierName: 'EXCLUSIVE CC MÍO 3B',
|
||||
supplierPhone: '573159876543',
|
||||
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 145000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 145000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 135000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Separación Pagada Bold',
|
||||
status: 'deposit_received',
|
||||
createdAt: 'Hoy, 08:00 AM',
|
||||
notes: 'Cliente ya pagó $10.000 de anticipo.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8925',
|
||||
customerName: 'Daniel Caicedo',
|
||||
customerPhone: '3174829105',
|
||||
address: 'Cra 10 # 3-45 San Antonio',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Oeste - San Antonio)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-af1-1',
|
||||
productName: 'Nike Air Force 1 07 Low Triple White',
|
||||
brand: 'Nike',
|
||||
size: '42',
|
||||
quantity: 1,
|
||||
price: 120000,
|
||||
supplierPrice: 80000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 120000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 120000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 110000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 08:20 AM',
|
||||
},
|
||||
];
|
||||
|
||||
class DataService {
|
||||
private products: Product[] = [...INITIAL_PRODUCTS];
|
||||
private cities: City[] = [...INITIAL_CITIES];
|
||||
private paymentMethods: PaymentMethod[] = [...INITIAL_PAYMENT_METHODS];
|
||||
private suppliers: Supplier[] = [...INITIAL_SUPPLIERS];
|
||||
private orders: Order[] = [];
|
||||
private orders: Order[] = [...INITIAL_ORDERS];
|
||||
private supplierPosts: SupplierPost[] = [...INITIAL_SUPPLIER_POSTS];
|
||||
|
||||
getProducts(): Product[] {
|
||||
@ -2225,6 +2387,30 @@ class DataService {
|
||||
return order;
|
||||
}
|
||||
|
||||
createOrder(orderData: Partial<Order>): Order {
|
||||
const newOrder: Order = {
|
||||
id: `ord-${Date.now()}`,
|
||||
customerName: orderData.customerName || 'Cliente',
|
||||
customerPhone: orderData.customerPhone || '',
|
||||
address: orderData.address || '',
|
||||
cityId: orderData.cityId || 'city-cali',
|
||||
cityName: orderData.cityName || 'Cali',
|
||||
items: orderData.items || [],
|
||||
subtotal: orderData.subtotal || 0,
|
||||
shippingCost: orderData.shippingCost || 0,
|
||||
totalAmount: orderData.totalAmount || 0,
|
||||
depositAmount: orderData.depositAmount || 10000,
|
||||
balanceDue: (orderData.totalAmount || 0) - (orderData.depositAmount || 10000),
|
||||
paymentMethodId: orderData.paymentMethodId || 'pay-contraentrega',
|
||||
paymentMethodName: orderData.paymentMethodName || 'Contraentrega',
|
||||
status: 'pending',
|
||||
notes: orderData.notes,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
this.orders.unshift(newOrder);
|
||||
return newOrder;
|
||||
}
|
||||
|
||||
updateOrderStatus(orderId: string, status: Order['status']): Order | null {
|
||||
const order = this.orders.find((o) => o.id === orderId);
|
||||
if (!order) return null;
|
||||
@ -2243,12 +2429,12 @@ class DataService {
|
||||
|
||||
// Configuración de la Tienda
|
||||
private settings: StoreSettings = {
|
||||
storeName: 'Sneaky Drops',
|
||||
slogan: 'Viral Sneakers & Exclusivos',
|
||||
storeName: 'DripZone',
|
||||
slogan: 'Luxury Streetwear & Collectibles',
|
||||
email: 'carlos.andres.lasso@gmail.com',
|
||||
phone: '3167455877',
|
||||
whatsappNumber: '573167455877',
|
||||
instagramHandle: '@sneakydrops.co',
|
||||
instagramHandle: '@dripzone.co',
|
||||
address: 'Bodega Central / Cali',
|
||||
city: 'Cali, Colombia',
|
||||
nequiAccount: '316 745 5877',
|
||||
@ -2290,7 +2476,7 @@ class DataService {
|
||||
{
|
||||
id: 'usr-operator-1',
|
||||
name: 'Andrés Operador Despachos',
|
||||
email: 'despachos@sneakydrops.co',
|
||||
email: 'despachos@dripzone.co',
|
||||
phone: '3159876543',
|
||||
city: 'Cali',
|
||||
role: 'operator',
|
||||
@ -2364,7 +2550,6 @@ class DataService {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const dataService = new DataService();
|
||||
|
||||
@ -2138,12 +2138,174 @@ export const INITIAL_MONITORED_GROUPS: MonitoredWhatsAppGroup[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const INITIAL_ORDERS: Order[] = [
|
||||
{
|
||||
id: 'ORD-8921',
|
||||
customerName: 'Mateo Valencia',
|
||||
customerPhone: '3168945120',
|
||||
address: 'Av 6N # 24N-32 Edificio Granada Real',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Norte - Granada)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-jordan4-1',
|
||||
productName: 'Nike Air Jordan 4 Retro White Cement',
|
||||
brand: 'Jordan',
|
||||
size: '41',
|
||||
quantity: 1,
|
||||
price: 135000,
|
||||
supplierPrice: 95000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1584735935682-2f2b69dff9d2?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 135000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 135000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 125000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega Efectivo / Nequi',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 06:45 AM',
|
||||
notes: 'Timbrar en apto 302. Paga con billete de 100 y 50.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8922',
|
||||
customerName: 'Valentina Restrepo',
|
||||
customerPhone: '3157829401',
|
||||
address: 'Calle 52N # 4BN-15 Casa 4 La Flora',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Norte - La Flora)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-vomero5-1',
|
||||
productName: 'Nike Zoom Vomero 5 Photon Dust Metallic Silver',
|
||||
brand: 'Nike',
|
||||
size: '39',
|
||||
quantity: 1,
|
||||
price: 130000,
|
||||
supplierPrice: 90000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 130000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 130000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 120000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega Nequi',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 07:15 AM',
|
||||
notes: 'Dejar en portería si no contesta.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8923',
|
||||
customerName: 'Santiago Henao',
|
||||
customerPhone: '3186523910',
|
||||
address: 'Cra 105 # 14-45 Condominio Portal de la Viga',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Sur - Ciudad Jardín)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-campus-1',
|
||||
productName: 'Adidas Campus 00s Core Black White',
|
||||
brand: 'Adidas',
|
||||
size: '40',
|
||||
quantity: 1,
|
||||
price: 125000,
|
||||
supplierPrice: 85000,
|
||||
supplierName: 'EXCLUSIVE CC MÍO 3B',
|
||||
supplierPhone: '573159876543',
|
||||
image: 'https://images.unsplash.com/photo-1525966222134-fcfa99b8ae77?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 125000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 125000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 115000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 07:30 AM',
|
||||
notes: 'Recibe en horas de la tarde después de las 2 PM.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8924',
|
||||
customerName: 'Camila Ospina',
|
||||
customerPhone: '3114958203',
|
||||
address: 'Cra 85E # 14-80 Apto 501 El Ingenio',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Sur - El Ingenio)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-coach-1',
|
||||
productName: 'Coach Low Top Monogram Signature Brown',
|
||||
brand: 'Coach',
|
||||
size: '38',
|
||||
quantity: 1,
|
||||
price: 145000,
|
||||
supplierPrice: 100000,
|
||||
supplierName: 'EXCLUSIVE CC MÍO 3B',
|
||||
supplierPhone: '573159876543',
|
||||
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 145000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 145000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 135000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Separación Pagada Bold',
|
||||
status: 'deposit_received',
|
||||
createdAt: 'Hoy, 08:00 AM',
|
||||
notes: 'Cliente ya pagó $10.000 de anticipo.',
|
||||
},
|
||||
{
|
||||
id: 'ORD-8925',
|
||||
customerName: 'Daniel Caicedo',
|
||||
customerPhone: '3174829105',
|
||||
address: 'Cra 10 # 3-45 San Antonio',
|
||||
cityId: 'city-cali',
|
||||
cityName: 'Cali (Oeste - San Antonio)',
|
||||
items: [
|
||||
{
|
||||
productId: 'snk-af1-1',
|
||||
productName: 'Nike Air Force 1 07 Low Triple White',
|
||||
brand: 'Nike',
|
||||
size: '42',
|
||||
quantity: 1,
|
||||
price: 120000,
|
||||
supplierPrice: 80000,
|
||||
supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀',
|
||||
supplierPhone: '573134848203',
|
||||
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
|
||||
},
|
||||
],
|
||||
subtotal: 120000,
|
||||
shippingCost: 0,
|
||||
totalAmount: 120000,
|
||||
depositAmount: 10000,
|
||||
balanceDue: 110000,
|
||||
paymentMethodId: 'pay-contraentrega',
|
||||
paymentMethodName: 'Contraentrega',
|
||||
status: 'pending',
|
||||
createdAt: 'Hoy, 08:20 AM',
|
||||
},
|
||||
];
|
||||
|
||||
class DataService {
|
||||
private products: Product[] = [...INITIAL_PRODUCTS];
|
||||
private cities: City[] = [...INITIAL_CITIES];
|
||||
private paymentMethods: PaymentMethod[] = [...INITIAL_PAYMENT_METHODS];
|
||||
private suppliers: Supplier[] = [...INITIAL_SUPPLIERS];
|
||||
private orders: Order[] = [];
|
||||
private orders: Order[] = [...INITIAL_ORDERS];
|
||||
private supplierPosts: SupplierPost[] = [...INITIAL_SUPPLIER_POSTS];
|
||||
|
||||
getProducts(): Product[] {
|
||||
@ -2225,6 +2387,30 @@ class DataService {
|
||||
return order;
|
||||
}
|
||||
|
||||
createOrder(orderData: Partial<Order>): Order {
|
||||
const newOrder: Order = {
|
||||
id: `ord-${Date.now()}`,
|
||||
customerName: orderData.customerName || 'Cliente',
|
||||
customerPhone: orderData.customerPhone || '',
|
||||
address: orderData.address || '',
|
||||
cityId: orderData.cityId || 'city-cali',
|
||||
cityName: orderData.cityName || 'Cali',
|
||||
items: orderData.items || [],
|
||||
subtotal: orderData.subtotal || 0,
|
||||
shippingCost: orderData.shippingCost || 0,
|
||||
totalAmount: orderData.totalAmount || 0,
|
||||
depositAmount: orderData.depositAmount || 10000,
|
||||
balanceDue: (orderData.totalAmount || 0) - (orderData.depositAmount || 10000),
|
||||
paymentMethodId: orderData.paymentMethodId || 'pay-contraentrega',
|
||||
paymentMethodName: orderData.paymentMethodName || 'Contraentrega',
|
||||
status: 'pending',
|
||||
notes: orderData.notes,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
this.orders.unshift(newOrder);
|
||||
return newOrder;
|
||||
}
|
||||
|
||||
updateOrderStatus(orderId: string, status: Order['status']): Order | null {
|
||||
const order = this.orders.find((o) => o.id === orderId);
|
||||
if (!order) return null;
|
||||
@ -2243,12 +2429,12 @@ class DataService {
|
||||
|
||||
// Configuración de la Tienda
|
||||
private settings: StoreSettings = {
|
||||
storeName: 'Zapply Cali',
|
||||
slogan: 'Sneakers Express • Entregas en 24 Horas',
|
||||
storeName: 'DripZone',
|
||||
slogan: 'Luxury Streetwear & Collectibles',
|
||||
email: 'carlos.andres.lasso@gmail.com',
|
||||
phone: '3167455877',
|
||||
whatsappNumber: '573167455877',
|
||||
instagramHandle: '@zapplycali.co',
|
||||
instagramHandle: '@dripzone.co',
|
||||
address: 'Bodega Central / Cali',
|
||||
city: 'Cali, Colombia',
|
||||
nequiAccount: '316 745 5877',
|
||||
@ -2290,7 +2476,7 @@ class DataService {
|
||||
{
|
||||
id: 'usr-operator-1',
|
||||
name: 'Andrés Operador Despachos',
|
||||
email: 'despachos@zapply.co',
|
||||
email: 'despachos@dripzone.co',
|
||||
phone: '3159876543',
|
||||
city: 'Cali',
|
||||
role: 'operator',
|
||||
@ -2364,7 +2550,6 @@ class DataService {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const dataService = new DataService();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user