Chuyển tới nội dung chính

Quản lý Dòng tiền - Cashflow Management

1. Tổng quan

1.1. Tại sao Cashflow quan trọng?

Sự thật về Agency: Agency không chết vì lỗ ads. Agency chết vì thiếu cashflow:

TikTok campaign hoàn thành → Đạt KPI → Nhưng chưa nghiệm thu
Facebook campaign đang chạy → Cần tiền → Nhưng chưa thu được tiền TikTok
→ Thiếu tiền chạy ads
→ Campaign bị dừng
→ Không hoàn thành KPI
→ Không nghiệm thu được
→ Vòng xoáy chết

Giải pháp: Quản lý chặt chẽ dòng tiền vào/ra.

1.2. Hai loại dòng tiền

Dòng tiền RA (Cash Outflow)

  • Ads spend (Meta, TikTok, Google)
  • Vendor payments (Web dev, Designers, Freelancers)
  • Infrastructure cost (Hosting, Tools, Software)
  • Operational cost (Salaries, Office)

Dòng tiền VÀO (Cash Inflow)

  • Client payments (theo milestone)
  • Retainer fees
  • Project deliveries

2. Payment Milestone

2.1. Khái niệm

Payment Milestone là mốc thanh toán gắn với mỗi Scope, định nghĩa:

  • Khi nào được xuất hóa đơn
  • Bao nhiêu tiền
  • Điều kiện gì cần đạt (KPI, deliverable)

2.2. Schema

{
"milestone_id": "MLS-001",
"scope_id": "SCP-2026-001",
"contract_code": "KWP2026",
"scope_code": "FB01",

"name": "Phase 1 - Q1 2026",
"description": "First quarter lead generation",

// Timeline
"due_date": "2026-03-31",
"invoice_date": "2026-04-05",
"payment_due_date": "2026-04-20",

// Money
"amount": 300000000,

// Acceptance criteria
"kpi_required": 15000, // For ads scope
"deliverable": "15,000 qualified leads", // For project scope
"acceptance_criteria": "Leads with complete contact info, verified phone",

// Status tracking
"status": "pending", // pending, ready_to_invoice, invoiced, paid
"invoice_number": null,
"payment_received_date": null,

"notes": "Customer expects report by April 3rd"
}

2.3. Milestone Status Flow

pending
↓ (KPI achieved \>= kpi_required)
ready_to_invoice
↓ (Invoice issued)
invoiced
↓ (Payment received)
paid

2.4. Use Cases

UC-CF-01: Tạo Payment Milestone

Actor: Kế toán

Main Flow:

  1. Kế toán chọn scope
  2. Click "Add Milestone"
  3. Nhập thông tin:
    • Name (Phase 1, Phase 2, Q1, Q2...)
    • Due date
    • Amount
    • KPI required (cho ads) hoặc Deliverable (cho project)
    • Acceptance criteria
    • Invoice date & Payment due date
  4. Hệ thống validate:
    SUM(milestone.amount for scope) \<= scope.revenue
    due_date \<= scope.end_date
  5. Hệ thống tạo milestone với status = "pending"
  6. Hệ thống schedule auto-check KPI daily

Postcondition:

  • Milestone được tạo
  • Auto-tracking được kích hoạt

UC-CF-02: Auto-check điều kiện nghiệm thu

Actor: System (auto, daily)

Main Flow:

  1. Hệ thống loop through tất cả milestone với status = "pending"

  2. Cho mỗi milestone:

    if milestone.scope.service_type == "ads":
    # Check KPI
    kpi_achieved = get_kpi_achieved(milestone.scope_id)
    if kpi_achieved \>= milestone.kpi_required:
    milestone.status = "ready_to_invoice"
    send_notification("Milestone ready to invoice")

    elif milestone.scope.service_type in ["web", "app"]:
    # Check deliverable (manual confirm by PM)
    if milestone.deliverable_confirmed_by_pm:
    milestone.status = "ready_to_invoice"
    send_notification("Milestone ready to invoice")
  3. Nếu milestone chuyển sang "ready_to_invoice":

    • Email to Kế toán: "Milestone XYZ ready - please issue invoice"
    • Create task in accounting system
    • Add to pending invoice list

Example Output:

🎉 MILESTONE READY FOR INVOICING

Scope: FB01 - Facebook Lead Generation
Milestone: Phase 1 - Q1 2026
Due date: 2026-03-31

✓ KPI Required: 15,000 leads
✓ KPI Achieved: 15,234 leads (101.6%)

Amount: 300,000,000 VND

ACTION: Please issue invoice to client
Invoice due date: 2026-04-05
Payment due date: 2026-04-20

UC-CF-03: Xuất hóa đơn (Issue Invoice)

Actor: Kế toán

Precondition:

  • Milestone.status = "ready_to_invoice"

Main Flow:

  1. Kế toán review milestone details
  2. Generate invoice (using accounting system or manually)
  3. Send invoice to client
  4. Update milestone:
    milestone.status = "invoiced"
    milestone.invoice_number = "INV-2026-001"
    milestone.invoice_date = today
  5. Hệ thống tạo receivable entry:
    {
    "invoice_number": "INV-2026-001",
    "client": "Kewpie Vietnam",
    "amount": 300000000,
    "due_date": "2026-04-20",
    "status": "outstanding"
    }
  6. Hệ thống schedule payment reminder
  7. Notification to Finance team

Postcondition:

  • Invoice issued
  • Receivable tracked
  • Payment reminder scheduled

UC-CF-04: Ghi nhận thanh toán (Record Payment)

Actor: Kế toán

Main Flow:

  1. Client chuyển khoản
  2. Kế toán confirm payment received
  3. Update milestone:
    milestone.status = "paid"
    milestone.payment_received_date = today
  4. Update receivable:
    receivable.status = "paid"
    receivable.paid_date = today
  5. Hệ thống update cashflow forecast
  6. Notification to Finance & PM

Postcondition:

  • Payment recorded
  • Cashflow updated
  • Can use this money for upcoming campaigns

3. Cashflow Forecasting

3.1. Dòng tiền RA (Outgoing)

3.1.1. Ads Spend Forecast

-- Forecast ads spend for next 3 months
SELECT
DATE_TRUNC('month', cp.date) AS month,
SUM(cp.daily_budget_cap * DAYS_IN_MONTH) AS forecasted_spend
FROM campaign_plan cp
WHERE cp.status = 'active'
AND cp.date \>= CURRENT_DATE
AND cp.date \< CURRENT_DATE + INTERVAL '3 months'
GROUP BY month
ORDER BY month;

Example Output:

Month      | Forecasted Spend
-----------|-----------------
2026-02 | 450,000,000 VND
2026-03 | 520,000,000 VND
2026-04 | 480,000,000 VND

3.1.2. Vendor Payment Forecast

-- Forecast vendor payments
SELECT
DATE_TRUNC('month', vp.due_date) AS month,
SUM(vp.amount) AS vendor_payments
FROM vendor_payment vp
WHERE vp.status IN ('pending', 'approved')
AND vp.due_date \>= CURRENT_DATE
AND vp.due_date \< CURRENT_DATE + INTERVAL '3 months'
GROUP BY month
ORDER BY month;

Example Output:

Month      | Vendor Payments
-----------|----------------
2026-02 | 85,000,000 VND
2026-03 | 120,000,000 VND
2026-04 | 60,000,000 VND

3.1.3. Total Outgoing Forecast

def forecast_cash_outflow(months=3):
"""Forecast total cash outflow"""
forecast = []

for i in range(months):
month_start = first_day_of_month(i)
month_end = last_day_of_month(i)

# Ads spend
ads_spend = sum_campaign_budget(month_start, month_end)

# Vendor payments
vendor_cost = sum_vendor_payments_due(month_start, month_end)

# Infrastructure
infra_cost = sum_infrastructure_cost(month_start, month_end)

# Total
total_outflow = ads_spend + vendor_cost + infra_cost

forecast.append({
'month': month_start.strftime('%Y-%m'),
'ads_spend': ads_spend,
'vendor_cost': vendor_cost,
'infra_cost': infra_cost,
'total_outflow': total_outflow
})

return forecast

Dashboard Display:

CASH OUTFLOW FORECAST (Next 3 Months)
─────────────────────────────────────────────────────────────
Month | Ads Spend | Vendor | Infra | TOTAL OUTFLOW
─────────────────────────────────────────────────────────────
Feb 2026 | 450M | 85M | 15M | 550M
Mar 2026 | 520M | 120M | 15M | 655M
Apr 2026 | 480M | 60M | 15M | 555M
─────────────────────────────────────────────────────────────
TOTAL | 1,760M

3.2. Dòng tiền VÀO (Incoming)

3.2.1. Expected Revenue from Milestones

-- Forecast cash inflow based on milestones
SELECT
DATE_TRUNC('month', pm.payment_due_date) AS month,
SUM(pm.amount) AS expected_revenue,
SUM(CASE WHEN pm.status = 'ready_to_invoice' THEN pm.amount ELSE 0 END) AS ready_to_invoice,
SUM(CASE WHEN pm.status = 'invoiced' THEN pm.amount ELSE 0 END) AS invoiced,
SUM(CASE WHEN pm.status = 'paid' THEN pm.amount ELSE 0 END) AS paid
FROM payment_milestone pm
WHERE pm.payment_due_date \>= CURRENT_DATE
AND pm.payment_due_date \< CURRENT_DATE + INTERVAL '3 months'
GROUP BY month
ORDER BY month;

Example Output:

Month    | Expected | Ready | Invoiced | Paid
---------|----------|-------|----------|------
Feb 2026 | 600M | 300M | 200M | 100M
Mar 2026 | 750M | 0 | 0 | 0
Apr 2026 | 500M | 0 | 0 | 0

3.2.2. Risk Assessment

def assess_milestone_risk(milestone):
"""Assess risk of milestone not being achieved on time"""
if milestone.scope.service_type == "ads":
# Check KPI pace
days_elapsed = (today - milestone.scope.start_date).days
days_total = (milestone.due_date - milestone.scope.start_date).days
expected_progress = days_elapsed / days_total

kpi_achieved = get_kpi_achieved(milestone.scope_id)
actual_progress = kpi_achieved / milestone.kpi_required

gap = actual_progress - expected_progress

if gap \< -0.2:
return "high_risk"
elif gap \< -0.1:
return "medium_risk"
else:
return "low_risk"

return "unknown"

Dashboard Display:

CASH INFLOW FORECAST (Next 3 Months)
─────────────────────────────────────────────────────────────
Milestone | Due Date | Amount | KPI % | Risk
─────────────────────────────────────────────────────────────
FB01 - Phase 1 | 2026-03-31 | 300M | 101% | ✓ Low
TT01 - Phase 1 | 2026-06-30 | 250M | 85% | ⚠ Med
WEB01 - Go-live | 2026-02-28 | 25M | N/A | ✓ Low
FB01 - Phase 2 | 2026-06-30 | 400M | 32% | 🔴 High
─────────────────────────────────────────────────────────────

3.3. Net Cashflow

def calculate_net_cashflow(months=3):
"""Calculate net cashflow forecast"""
outflow = forecast_cash_outflow(months)
inflow = forecast_cash_inflow(months)

net_cashflow = []
cumulative = 0

for i in range(months):
monthly_net = inflow[i]['total'] - outflow[i]['total']
cumulative += monthly_net

net_cashflow.append({
'month': outflow[i]['month'],
'inflow': inflow[i]['total'],
'outflow': outflow[i]['total'],
'net': monthly_net,
'cumulative': cumulative
})

return net_cashflow

Dashboard Display:

NET CASHFLOW FORECAST
─────────────────────────────────────────────────────────────
Month | Inflow | Outflow | Net | Cumulative
─────────────────────────────────────────────────────────────
Feb 2026 | 600M | 550M | +50M | +50M
Mar 2026 | 750M | 655M | +95M | +145M
Apr 2026 | 500M | 555M | -55M | +90M
─────────────────────────────────────────────────────────────

⚠ WARNING: April shows negative cashflow (-55M)
Ensure Feb & Mar payments are collected on time.

4. Cashflow Alerts

4.1. Alert Types

Alert TypeTriggerSeverityAction
Negative CashflowNet < 0 trong bất kỳ tháng nàoHighFinance review, delay vendor payments
Low ReserveCumulative < 100MMediumDirector approval needed for new campaigns
Overdue InvoiceInvoice > 15 days overdueHighEscalate to Director, call client
At-risk MilestoneKPI gap < -20%MediumPM action plan required
Late Vendor PaymentPayment > 7 days overdueMediumAccounting follow-up

4.2. Use Cases

UC-CF-05: Cảnh báo dòng tiền âm

Trigger: Projected net cashflow < 0

Main Flow:

  1. Hệ thống detect negative cashflow trong forecast
  2. Tạo alert:
    🚨 NEGATIVE CASHFLOW ALERT

    Month: April 2026
    Projected Inflow: 500M
    Projected Outflow: 555M
    Net Cashflow: -55M

    Current Reserve: 145M (after Feb + Mar)
    After April: 90M

    RECOMMENDATIONS:
    1. Prioritize collecting Feb & Mar invoices on time
    2. Delay non-critical vendor payments to May
    3. Review if any campaigns can be postponed
    4. Consider requesting advance payment from clients

    ACTION REQUIRED: Finance Director approval
  3. Email to Finance + Director
  4. Create task for Finance team

UC-CF-06: Cảnh báo invoice quá hạn

Trigger: Invoice overdue > 15 days

Main Flow:

  1. Daily job check overdue invoices:

    overdue_invoices = get_invoices_where(
    status = 'invoiced',
    payment_due_date \< today - 15 days
    )
  2. Cho mỗi overdue invoice:

    ⚠ OVERDUE INVOICE ALERT

    Invoice: INV-2026-001
    Client: Kewpie Vietnam
    Amount: 300,000,000 VND
    Due date: 2026-04-20
    Days overdue: 18 days

    This affects cashflow for:
    - May campaigns: Need 520M, at risk of underfunding

    ACTION REQUIRED:
    1. Call client immediately
    2. Send payment reminder
    3. Escalate to Director if no response in 3 days
  3. Email to Kế toán + Finance + Director

  4. Auto-send payment reminder to client

  5. Update invoice status: "overdue"


5. Scenario Planning

5.1. Best Case Scenario

Assumptions:
- All milestones achieved on time
- All invoices paid on due date
- No campaign delays

Result:
- Positive cashflow every month
- Reserve grows to 500M by year end

5.2. Realistic Scenario

Assumptions:
- 90% milestones achieved on time
- Average payment delay: 10 days
- 5% campaign budget overruns

Result:
- 1-2 months with tight cashflow
- Reserve: 300M by year end
- Manageable with planning

5.3. Worst Case Scenario

Assumptions:
- 70% milestones achieved on time
- Average payment delay: 30 days
- 15% campaign budget overruns

Result:
- 3 months with negative cashflow
- Need external financing: 200M
- High risk of campaign pauses

5.4. Scenario Dashboard

def calculate_scenarios():
"""Calculate multiple scenarios"""
scenarios = {
'best': {
'milestone_success_rate': 1.0,
'payment_delay_days': 0,
'budget_overrun': 0
},
'realistic': {
'milestone_success_rate': 0.9,
'payment_delay_days': 10,
'budget_overrun': 0.05
},
'worst': {
'milestone_success_rate': 0.7,
'payment_delay_days': 30,
'budget_overrun': 0.15
}
}

results = {}
for name, params in scenarios.items():
results[name] = simulate_cashflow(params)

return results

6. Integration với Accounting System

6.1. Xuất Invoice Data

def export_invoice_data(milestone):
"""Export invoice data to accounting system"""
invoice_data = {
'invoice_number': milestone.invoice_number,
'client_id': milestone.scope.contract.client_id,
'client_name': milestone.scope.contract.client_name,
'amount': milestone.amount,
'tax_rate': 0.1, # 10% VAT
'amount_with_tax': milestone.amount * 1.1,
'issue_date': milestone.invoice_date,
'due_date': milestone.payment_due_date,
'description': f"{milestone.scope.name} - {milestone.name}",
'items': [
```json
{
'description': milestone.deliverable,
'quantity': 1,
'unit_price': milestone.amount,
'amount': milestone.amount
}

] }

Send to accounting system API

accounting_api.create_invoice(invoice_data)


### 6.2. Sync Payment Status
```python
def sync_payment_status():
"""Sync payment status from accounting system"""
# Get paid invoices from accounting system
paid_invoices = accounting_api.get_paid_invoices_since(last_sync)

for invoice in paid_invoices:
# Find corresponding milestone
milestone = get_milestone_by_invoice_number(invoice.invoice_number)

if milestone and milestone.status != 'paid':
# Update milestone
milestone.status = 'paid'
milestone.payment_received_date = invoice.paid_date
milestone.save()

# Trigger notifications
notify_payment_received(milestone)

# Update cashflow
update_cashflow_actual(milestone)

7. Reports & Dashboards

7.1. Cashflow Summary Report

CASHFLOW SUMMARY - Q1 2026
═════════════════════════════════════════════════════════════

INFLOW
──────────────────────────────────────────────────────────────
Milestones Paid: 1,850M
Retainer Fees: 150M
Other Revenue: 50M
──────
TOTAL INFLOW: 2,050M

OUTFLOW
──────────────────────────────────────────────────────────────
Ads Spend: 1,450M
Vendor Payments: 265M
Infrastructure: 45M
Operations: 200M
──────
TOTAL OUTFLOW: 1,960M

NET CASHFLOW: +90M
══════════════════════════════════════════════════════════════

Opening Balance: 200M
Closing Balance: 290M

Reserve Target: 500M
Gap to Target: -210M

7.2. Aging Report (Receivables)

ACCOUNTS RECEIVABLE AGING
═════════════════════════════════════════════════════════════
Client | Invoice | Amount | Current | 1-30 | 31-60 | 60+
─────────────────────────────────────────────────────────────
Kewpie | INV-001 | 300M | | 300M | |
Vinamilk | INV-002 | 450M | 450M | | |
Grab | INV-003 | 200M | | | 200M |
─────────────────────────────────────────────────────────────
TOTAL | 950M | 450M | 300M | 200M | 0

7.3. Cash Position Chart

  • Line chart: Cumulative cashflow over time
  • Bar chart: Monthly inflow vs outflow
  • Waterfall chart: Opening → Inflow → Outflow → Closing

8. Best Practices

8.1. Milestone Setup

  1. Align với contract phases: Chia milestone theo giai đoạn tự nhiên
  2. Realistic KPI: Không set KPI quá cao làm khó nghiệm thu
  3. Buffer time: Due date nên sớm hơn contract end date 1-2 tuần
  4. Clear criteria: Acceptance criteria phải rõ ràng, measurable

8.2. Invoice Management

  1. Issue promptly: Xuất invoice ngay khi milestone ready
  2. Follow up: Gọi điện confirm client nhận invoice
  3. Payment reminder: Gửi reminder 3 ngày trước due date
  4. Escalate early: Nếu quá 7 ngày chưa nhận tiền, escalate to Director

8.3. Cashflow Planning

  1. 3-month forecast: Luôn có forecast cho 3 tháng tới
  2. Update weekly: Update forecast mỗi tuần dựa trên actual data
  3. Reserve fund: Maintain ít nhất 2 tháng outflow làm reserve
  4. Scenario planning: Review worst case scenario quarterly

8.4. Risk Mitigation

  1. Diversify clients: Không để 1 client chiếm >30% revenue
  2. Advance payment: Negotiate 30-50% advance cho new clients
  3. Payment terms: Net 15 tốt hơn Net 30
  4. Vendor terms: Negotiate Net 30-45 với vendors

9. KPIs for Cashflow Management

KPITargetFormula
Days Sales Outstanding (DSO)< 30 daysAverage Receivables / (Revenue / 365)
Collection Rate> 95%Amount Collected / Amount Invoiced
On-time Payment Rate> 80%Invoices Paid On Time / Total Invoices
Cash Conversion Cycle< 45 daysDSO + Days Inventory - Days Payable
Cash Reserve Ratio> 2xCash Balance / Monthly Outflow

10. Emergency Procedures

10.1. Khi thiếu cashflow đột ngột

Immediate Actions (Day 1-3):

  1. Call all clients with overdue invoices
  2. Offer discount for early payment (2-3%)
  3. Delay all non-critical vendor payments
  4. Pause new campaign spending

Short-term (Week 1-2): 5. Negotiate payment plan with vendors 6. Request advance payment for ongoing projects 7. Consider short-term financing

Medium-term (Month 1): 8. Review and optimize all contracts 9. Renegotiate payment terms with clients 10. Build cash reserve from profitable projects

10.2. Escalation Path

Level 1: Finance Team (Day 1-3)
→ Can delay vendor payments, send reminders

Level 2: Finance Director (Day 4-7)
→ Can negotiate with clients, approve short-term financing

Level 3: CEO (Day 8+)
→ Strategic decisions: pause operations, external financing