462 lines
18 KiB
QBasic
462 lines
18 KiB
QBasic
|
|
REM CRM Automations - Follow-ups, Collections, Lead Nurturing, Sales Pipeline
|
||
|
|
REM Scheduled jobs that run automatically to handle common CRM workflows.
|
||
|
|
REM Uses the new attendance keywords for queue integration.
|
||
|
|
REM
|
||
|
|
REM Schedules:
|
||
|
|
REM SET SCHEDULE "follow-ups", "0 9 * * 1-5" (9am weekdays)
|
||
|
|
REM SET SCHEDULE "collections", "0 8 * * 1-5" (8am weekdays)
|
||
|
|
REM SET SCHEDULE "lead-nurture", "0 10 * * 1-5" (10am weekdays)
|
||
|
|
REM SET SCHEDULE "pipeline-review", "0 14 * * 5" (2pm Fridays)
|
||
|
|
|
||
|
|
PARAM job_name AS STRING LIKE "follow-ups" DESCRIPTION "Job to run: follow-ups, collections, lead-nurture, pipeline-review, all"
|
||
|
|
|
||
|
|
DESCRIPTION "Automated CRM workflows for follow-ups, collections, lead nurturing, and pipeline management"
|
||
|
|
|
||
|
|
PRINT "=== CRM Automations Starting: " + job_name + " ==="
|
||
|
|
PRINT "Time: " + FORMAT(NOW(), "yyyy-MM-dd HH:mm:ss")
|
||
|
|
|
||
|
|
results = {}
|
||
|
|
results.job = job_name
|
||
|
|
results.started_at = NOW()
|
||
|
|
results.actions = []
|
||
|
|
|
||
|
|
' =====================================================================
|
||
|
|
' FOLLOW-UPS - Automated follow-up sequences
|
||
|
|
' =====================================================================
|
||
|
|
IF job_name = "follow-ups" OR job_name = "all" THEN
|
||
|
|
PRINT ""
|
||
|
|
PRINT "--- Running Follow-ups ---"
|
||
|
|
|
||
|
|
' 1-day follow-up: Thank you message for new leads
|
||
|
|
leads_1_day = FIND "leads", "status='new' AND DATEDIFF(NOW(), created_at) = 1"
|
||
|
|
PRINT "1-day follow-ups: " + UBOUND(leads_1_day)
|
||
|
|
|
||
|
|
FOR EACH lead IN leads_1_day
|
||
|
|
' Send thank you message
|
||
|
|
IF lead.phone IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE lead.phone, "follow_up_thanks", {
|
||
|
|
"name": lead.name,
|
||
|
|
"interest": lead.interest OR "our services"
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF lead.email IS NOT NULL THEN
|
||
|
|
SEND MAIL lead.email, "Obrigado pelo seu interesse!", "Olá " + lead.name + ",\n\nObrigado por entrar em contato conosco. Estamos à disposição para ajudá-lo.\n\nAtenciosamente,\nEquipe de Vendas"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Update lead status
|
||
|
|
UPDATE "leads", "id='" + lead.id + "'", {
|
||
|
|
"status": "contacted",
|
||
|
|
"last_contact": NOW(),
|
||
|
|
"follow_up_1_sent": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
' Log activity
|
||
|
|
SAVE "activities", {
|
||
|
|
"type": "follow_up",
|
||
|
|
"lead_id": lead.id,
|
||
|
|
"description": "1-day thank you sent",
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "follow_up_1", "lead": lead.name}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' 3-day follow-up: Value proposition
|
||
|
|
leads_3_day = FIND "leads", "status='contacted' AND DATEDIFF(NOW(), last_contact) = 3 AND follow_up_3_sent IS NULL"
|
||
|
|
PRINT "3-day follow-ups: " + UBOUND(leads_3_day)
|
||
|
|
|
||
|
|
FOR EACH lead IN leads_3_day
|
||
|
|
IF lead.phone IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE lead.phone, "follow_up_value", {
|
||
|
|
"name": lead.name,
|
||
|
|
"interest": lead.interest OR "our services"
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
UPDATE "leads", "id='" + lead.id + "'", {
|
||
|
|
"last_contact": NOW(),
|
||
|
|
"follow_up_3_sent": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
SAVE "activities", {
|
||
|
|
"type": "follow_up",
|
||
|
|
"lead_id": lead.id,
|
||
|
|
"description": "3-day value proposition sent",
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "follow_up_3", "lead": lead.name}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' 7-day follow-up: Special offer for hot leads
|
||
|
|
leads_7_day = FIND "leads", "status IN ('contacted', 'nurturing') AND DATEDIFF(NOW(), last_contact) = 7 AND follow_up_7_sent IS NULL AND score >= 50"
|
||
|
|
PRINT "7-day follow-ups: " + UBOUND(leads_7_day)
|
||
|
|
|
||
|
|
FOR EACH lead IN leads_7_day
|
||
|
|
IF lead.phone IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE lead.phone, "follow_up_offer", {
|
||
|
|
"name": lead.name,
|
||
|
|
"discount": "10%"
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
UPDATE "leads", "id='" + lead.id + "'", {
|
||
|
|
"status": "offer_sent",
|
||
|
|
"last_contact": NOW(),
|
||
|
|
"follow_up_7_sent": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
' Alert sales for hot leads
|
||
|
|
IF lead.score >= 70 THEN
|
||
|
|
attendants = GET ATTENDANTS "online"
|
||
|
|
FOR EACH att IN attendants.items
|
||
|
|
IF att.department = "commercial" OR att.preferences CONTAINS "sales" THEN
|
||
|
|
SEND MAIL att.email, "🔥 Hot Lead Follow-up: " + lead.name, "Lead " + lead.name + " recebeu oferta de 7 dias.\nScore: " + lead.score + "\nTelefone: " + lead.phone + "\n\nRecomendado: Entrar em contato nas próximas 24h."
|
||
|
|
END IF
|
||
|
|
NEXT
|
||
|
|
END IF
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "follow_up_7", "lead": lead.name, "score": lead.score}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
results.follow_ups_completed = UBOUND(leads_1_day) + UBOUND(leads_3_day) + UBOUND(leads_7_day)
|
||
|
|
PRINT "Follow-ups completed: " + results.follow_ups_completed
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' =====================================================================
|
||
|
|
' COLLECTIONS - Automated payment reminders (Cobranças)
|
||
|
|
' =====================================================================
|
||
|
|
IF job_name = "collections" OR job_name = "all" THEN
|
||
|
|
PRINT ""
|
||
|
|
PRINT "--- Running Collections ---"
|
||
|
|
|
||
|
|
' Due today: Friendly reminder
|
||
|
|
due_today = FIND "invoices", "status='pending' AND due_date = CURDATE()"
|
||
|
|
PRINT "Due today: " + UBOUND(due_today)
|
||
|
|
|
||
|
|
FOR EACH invoice IN due_today
|
||
|
|
customer = FIND "customers", "id='" + invoice.customer_id + "'"
|
||
|
|
|
||
|
|
IF customer.phone IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE customer.phone, "payment_due_today", {
|
||
|
|
"name": customer.name,
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"amount": FORMAT(invoice.amount, "R$ #,##0.00")
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
SAVE "collection_log", {
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"action": "reminder_due_today",
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "payment_reminder", "customer": customer.name, "days": 0}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' 3 days overdue: First notice
|
||
|
|
overdue_3 = FIND "invoices", "status='pending' AND DATEDIFF(NOW(), due_date) = 3"
|
||
|
|
PRINT "3 days overdue: " + UBOUND(overdue_3)
|
||
|
|
|
||
|
|
FOR EACH invoice IN overdue_3
|
||
|
|
customer = FIND "customers", "id='" + invoice.customer_id + "'"
|
||
|
|
|
||
|
|
IF customer.phone IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE customer.phone, "payment_overdue_3", {
|
||
|
|
"name": customer.name,
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"amount": FORMAT(invoice.amount, "R$ #,##0.00")
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF customer.email IS NOT NULL THEN
|
||
|
|
SEND MAIL customer.email, "Pagamento Pendente - Fatura #" + invoice.id, "Prezado(a) " + customer.name + ",\n\nSua fatura #" + invoice.id + " no valor de R$ " + invoice.amount + " está vencida há 3 dias.\n\nPor favor, regularize o pagamento para evitar encargos adicionais.\n\nEm caso de dúvidas, entre em contato conosco.\n\nAtenciosamente,\nDepartamento Financeiro"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
UPDATE "invoices", "id='" + invoice.id + "'", {
|
||
|
|
"first_notice_sent": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
SAVE "collection_log", {
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"action": "first_notice",
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "collection_notice_1", "customer": customer.name}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' 7 days overdue: Second notice with urgency
|
||
|
|
overdue_7 = FIND "invoices", "status='pending' AND DATEDIFF(NOW(), due_date) = 7"
|
||
|
|
PRINT "7 days overdue: " + UBOUND(overdue_7)
|
||
|
|
|
||
|
|
FOR EACH invoice IN overdue_7
|
||
|
|
customer = FIND "customers", "id='" + invoice.customer_id + "'"
|
||
|
|
|
||
|
|
IF customer.phone IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE customer.phone, "payment_overdue_7", {
|
||
|
|
"name": customer.name,
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"amount": FORMAT(invoice.amount, "R$ #,##0.00")
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
UPDATE "invoices", "id='" + invoice.id + "'", {
|
||
|
|
"second_notice_sent": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
' Notify collections team
|
||
|
|
SEND MAIL "cobranca@company.com", "Cobrança 7 dias: " + customer.name, "Cliente: " + customer.name + "\nFatura: " + invoice.id + "\nValor: R$ " + invoice.amount + "\nTelefone: " + customer.phone
|
||
|
|
|
||
|
|
SAVE "collection_log", {
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"action": "second_notice",
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "collection_notice_2", "customer": customer.name}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' 15 days overdue: Final notice + queue for human call
|
||
|
|
overdue_15 = FIND "invoices", "status='pending' AND DATEDIFF(NOW(), due_date) = 15"
|
||
|
|
PRINT "15 days overdue: " + UBOUND(overdue_15)
|
||
|
|
|
||
|
|
FOR EACH invoice IN overdue_15
|
||
|
|
customer = FIND "customers", "id='" + invoice.customer_id + "'"
|
||
|
|
|
||
|
|
' Calculate late fees
|
||
|
|
late_fee = invoice.amount * 0.02
|
||
|
|
interest = invoice.amount * 0.01 * 15
|
||
|
|
total_due = invoice.amount + late_fee + interest
|
||
|
|
|
||
|
|
IF customer.phone IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE customer.phone, "payment_final_notice", {
|
||
|
|
"name": customer.name,
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"total": FORMAT(total_due, "R$ #,##0.00")
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
UPDATE "invoices", "id='" + invoice.id + "'", {
|
||
|
|
"late_fee": late_fee,
|
||
|
|
"interest": interest,
|
||
|
|
"total_due": total_due,
|
||
|
|
"final_notice_sent": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
' Create task for human follow-up call
|
||
|
|
CREATE TASK "Ligar para cliente: " + customer.name + " - Cobrança 15 dias", "cobranca@company.com", NOW()
|
||
|
|
|
||
|
|
' Find finance attendant and assign
|
||
|
|
attendants = GET ATTENDANTS
|
||
|
|
FOR EACH att IN attendants.items
|
||
|
|
IF att.department = "finance" OR att.preferences CONTAINS "collections" THEN
|
||
|
|
' Create session for outbound call
|
||
|
|
SAVE "outbound_queue", {
|
||
|
|
"customer_id": customer.id,
|
||
|
|
"customer_name": customer.name,
|
||
|
|
"customer_phone": customer.phone,
|
||
|
|
"reason": "collection_15_days",
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"amount_due": total_due,
|
||
|
|
"assigned_to": att.id,
|
||
|
|
"priority": "high",
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
SAVE "collection_log", {
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"action": "final_notice",
|
||
|
|
"total_due": total_due,
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "collection_final", "customer": customer.name, "total": total_due}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' 30+ days: Send to legal/collections agency
|
||
|
|
overdue_30 = FIND "invoices", "status='pending' AND DATEDIFF(NOW(), due_date) >= 30 AND status <> 'collections'"
|
||
|
|
PRINT "30+ days overdue: " + UBOUND(overdue_30)
|
||
|
|
|
||
|
|
FOR EACH invoice IN overdue_30
|
||
|
|
customer = FIND "customers", "id='" + invoice.customer_id + "'"
|
||
|
|
|
||
|
|
UPDATE "invoices", "id='" + invoice.id + "'", {
|
||
|
|
"status": "collections",
|
||
|
|
"sent_to_collections": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
UPDATE "customers", "id='" + customer.id + "'", {
|
||
|
|
"status": "suspended"
|
||
|
|
}
|
||
|
|
|
||
|
|
SEND MAIL "juridico@company.com", "Inadimplência 30+ dias: " + customer.name, "Cliente enviado para cobrança jurídica.\n\nCliente: " + customer.name + "\nFatura: " + invoice.id + "\nValor total: R$ " + invoice.total_due + "\nDias em atraso: " + DATEDIFF(NOW(), invoice.due_date)
|
||
|
|
|
||
|
|
SAVE "collection_log", {
|
||
|
|
"invoice_id": invoice.id,
|
||
|
|
"action": "sent_to_legal",
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "collection_legal", "customer": customer.name}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
results.collections_processed = UBOUND(due_today) + UBOUND(overdue_3) + UBOUND(overdue_7) + UBOUND(overdue_15) + UBOUND(overdue_30)
|
||
|
|
PRINT "Collections processed: " + results.collections_processed
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' =====================================================================
|
||
|
|
' LEAD NURTURE - Re-engage cold leads
|
||
|
|
' =====================================================================
|
||
|
|
IF job_name = "lead-nurture" OR job_name = "all" THEN
|
||
|
|
PRINT ""
|
||
|
|
PRINT "--- Running Lead Nurture ---"
|
||
|
|
|
||
|
|
' Find cold leads that haven't been contacted in 30 days
|
||
|
|
cold_leads = FIND "leads", "status IN ('cold', 'nurturing') AND DATEDIFF(NOW(), last_contact) >= 30 AND DATEDIFF(NOW(), last_contact) < 90"
|
||
|
|
PRINT "Cold leads to nurture: " + UBOUND(cold_leads)
|
||
|
|
|
||
|
|
FOR EACH lead IN cold_leads
|
||
|
|
' Send nurture content based on interest
|
||
|
|
content_type = "general"
|
||
|
|
IF lead.interest CONTAINS "pricing" OR lead.interest CONTAINS "preço" THEN
|
||
|
|
content_type = "pricing_update"
|
||
|
|
ELSE IF lead.interest CONTAINS "feature" OR lead.interest CONTAINS "funcionalidade" THEN
|
||
|
|
content_type = "feature_update"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF lead.email IS NOT NULL THEN
|
||
|
|
SEND TEMPLATE lead.email, "nurture_" + content_type, {
|
||
|
|
"name": lead.name,
|
||
|
|
"company": lead.company
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
UPDATE "leads", "id='" + lead.id + "'", {
|
||
|
|
"last_contact": NOW(),
|
||
|
|
"nurture_count": (lead.nurture_count OR 0) + 1
|
||
|
|
}
|
||
|
|
|
||
|
|
SAVE "activities", {
|
||
|
|
"type": "nurture",
|
||
|
|
"lead_id": lead.id,
|
||
|
|
"description": "Nurture email sent: " + content_type,
|
||
|
|
"created_at": NOW()
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "nurture", "lead": lead.name, "content": content_type}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' Archive very old leads (90+ days, low score)
|
||
|
|
stale_leads = FIND "leads", "DATEDIFF(NOW(), last_contact) >= 90 AND score < 30 AND status <> 'archived'"
|
||
|
|
PRINT "Stale leads to archive: " + UBOUND(stale_leads)
|
||
|
|
|
||
|
|
FOR EACH lead IN stale_leads
|
||
|
|
UPDATE "leads", "id='" + lead.id + "'", {
|
||
|
|
"status": "archived",
|
||
|
|
"archived_at": NOW(),
|
||
|
|
"archive_reason": "No engagement after 90 days"
|
||
|
|
}
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "archive", "lead": lead.name}
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
results.leads_nurtured = UBOUND(cold_leads)
|
||
|
|
results.leads_archived = UBOUND(stale_leads)
|
||
|
|
PRINT "Leads nurtured: " + results.leads_nurtured + ", Archived: " + results.leads_archived
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' =====================================================================
|
||
|
|
' PIPELINE REVIEW - Weekly pipeline analysis
|
||
|
|
' =====================================================================
|
||
|
|
IF job_name = "pipeline-review" OR job_name = "all" THEN
|
||
|
|
PRINT ""
|
||
|
|
PRINT "--- Running Pipeline Review ---"
|
||
|
|
|
||
|
|
' Get all active opportunities
|
||
|
|
opportunities = FIND "opportunities", "stage NOT IN ('closed_won', 'closed_lost')"
|
||
|
|
PRINT "Active opportunities: " + UBOUND(opportunities)
|
||
|
|
|
||
|
|
' Calculate pipeline metrics
|
||
|
|
total_value = 0
|
||
|
|
weighted_value = 0
|
||
|
|
stale_count = 0
|
||
|
|
at_risk_count = 0
|
||
|
|
|
||
|
|
FOR EACH opp IN opportunities
|
||
|
|
total_value = total_value + opp.amount
|
||
|
|
weighted_value = weighted_value + (opp.amount * opp.probability / 100)
|
||
|
|
|
||
|
|
' Check for stale opportunities
|
||
|
|
days_since_activity = DATEDIFF(NOW(), opp.last_activity)
|
||
|
|
IF days_since_activity > 14 THEN
|
||
|
|
stale_count = stale_count + 1
|
||
|
|
|
||
|
|
' Alert owner
|
||
|
|
owner = FIND "attendants", "id='" + opp.owner_id + "'"
|
||
|
|
IF owner IS NOT NULL AND owner.email IS NOT NULL THEN
|
||
|
|
SEND MAIL owner.email, "⚠️ Oportunidade Estagnada: " + opp.name, "A oportunidade '" + opp.name + "' está sem atividade há " + days_since_activity + " dias.\n\nValor: R$ " + opp.amount + "\nEstágio: " + opp.stage + "\n\nPor favor, atualize o status ou registre uma atividade."
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Create task
|
||
|
|
CREATE TASK "Atualizar oportunidade: " + opp.name, owner.email, NOW()
|
||
|
|
|
||
|
|
APPEND results.actions, {"type": "stale_alert", "opportunity": opp.name, "days": days_since_activity}
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Check for at-risk (past close date)
|
||
|
|
IF opp.close_date < NOW() THEN
|
||
|
|
at_risk_count = at_risk_count + 1
|
||
|
|
|
||
|
|
UPDATE "opportunities", "id='" + opp.id + "'", {
|
||
|
|
"at_risk": TRUE,
|
||
|
|
"risk_reason": "Past expected close date"
|
||
|
|
}
|
||
|
|
END IF
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' Generate weekly report
|
||
|
|
report = "📊 PIPELINE SEMANAL\n"
|
||
|
|
report = report + "════════════════════════════════════════\n\n"
|
||
|
|
report = report + "Total Pipeline: R$ " + FORMAT(total_value, "#,##0.00") + "\n"
|
||
|
|
report = report + "Valor Ponderado: R$ " + FORMAT(weighted_value, "#,##0.00") + "\n"
|
||
|
|
report = report + "Oportunidades Ativas: " + UBOUND(opportunities) + "\n"
|
||
|
|
report = report + "Estagnadas (14+ dias): " + stale_count + "\n"
|
||
|
|
report = report + "Em Risco: " + at_risk_count + "\n\n"
|
||
|
|
|
||
|
|
' Top 5 opportunities
|
||
|
|
top_opps = FIND "opportunities", "stage NOT IN ('closed_won', 'closed_lost') ORDER BY amount DESC LIMIT 5"
|
||
|
|
report = report + "TOP 5 OPORTUNIDADES:\n"
|
||
|
|
FOR EACH opp IN top_opps
|
||
|
|
report = report + "• " + opp.name + " - R$ " + FORMAT(opp.amount, "#,##0.00") + " (" + opp.probability + "%)\n"
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
' Send to sales leadership
|
||
|
|
SEND MAIL "vendas@company.com", "Pipeline Semanal - " + FORMAT(NOW(), "dd/MM/yyyy"), report
|
||
|
|
|
||
|
|
results.pipeline_total = total_value
|
||
|
|
results.pipeline_weighted = weighted_value
|
||
|
|
results.stale_opportunities = stale_count
|
||
|
|
results.at_risk = at_risk_count
|
||
|
|
PRINT "Pipeline review completed. Total: R$ " + total_value
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' =====================================================================
|
||
|
|
' FINISH
|
||
|
|
' =====================================================================
|
||
|
|
results.completed_at = NOW()
|
||
|
|
results.duration_seconds = DATEDIFF("second", results.started_at, results.completed_at)
|
||
|
|
|
||
|
|
PRINT ""
|
||
|
|
PRINT "=== CRM Automations Completed ==="
|
||
|
|
PRINT "Duration: " + results.duration_seconds + " seconds"
|
||
|
|
PRINT "Actions taken: " + UBOUND(results.actions)
|
||
|
|
|
||
|
|
' Log results
|
||
|
|
SAVE "automation_logs", results
|
||
|
|
|
||
|
|
RETURN results
|