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:
- Kế toán chọn scope
- Click "Add Milestone"
- 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
- Hệ thống validate:
SUM(milestone.amount for scope) \<= scope.revenue
due_date \<= scope.end_date - Hệ thống tạo milestone với status = "pending"
- 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:
-
Hệ thống loop through tất cả milestone với status = "pending"
-
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") -
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:
- Kế toán review milestone details
- Generate invoice (using accounting system or manually)
- Send invoice to client
- Update milestone:
milestone.status = "invoiced"
milestone.invoice_number = "INV-2026-001"
milestone.invoice_date = today - Hệ thống tạo receivable entry:
{
"invoice_number": "INV-2026-001",
"client": "Kewpie Vietnam",
"amount": 300000000,
"due_date": "2026-04-20",
"status": "outstanding"
} - Hệ thống schedule payment reminder
- 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:
- Client chuyển khoản
- Kế toán confirm payment received
- Update milestone:
milestone.status = "paid"
milestone.payment_received_date = today - Update receivable:
receivable.status = "paid"
receivable.paid_date = today - Hệ thống update cashflow forecast
- 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 Type | Trigger | Severity | Action |
|---|---|---|---|
| Negative Cashflow | Net < 0 trong bất kỳ tháng nào | High | Finance review, delay vendor payments |
| Low Reserve | Cumulative < 100M | Medium | Director approval needed for new campaigns |
| Overdue Invoice | Invoice > 15 days overdue | High | Escalate to Director, call client |
| At-risk Milestone | KPI gap < -20% | Medium | PM action plan required |
| Late Vendor Payment | Payment > 7 days overdue | Medium | Accounting 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:
- Hệ thống detect negative cashflow trong forecast
- 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 - Email to Finance + Director
- Create task for Finance team
UC-CF-06: Cảnh báo invoice quá hạn
Trigger: Invoice overdue > 15 days
Main Flow:
-
Daily job check overdue invoices:
overdue_invoices = get_invoices_where(
status = 'invoiced',
payment_due_date \< today - 15 days
) -
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 -
Email to Kế toán + Finance + Director
-
Auto-send payment reminder to client
-
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
- Align với contract phases: Chia milestone theo giai đoạn tự nhiên
- Realistic KPI: Không set KPI quá cao làm khó nghiệm thu
- Buffer time: Due date nên sớm hơn contract end date 1-2 tuần
- Clear criteria: Acceptance criteria phải rõ ràng, measurable
8.2. Invoice Management
- Issue promptly: Xuất invoice ngay khi milestone ready
- Follow up: Gọi điện confirm client nhận invoice
- Payment reminder: Gửi reminder 3 ngày trước due date
- Escalate early: Nếu quá 7 ngày chưa nhận tiền, escalate to Director
8.3. Cashflow Planning
- 3-month forecast: Luôn có forecast cho 3 tháng tới
- Update weekly: Update forecast mỗi tuần dựa trên actual data
- Reserve fund: Maintain ít nhất 2 tháng outflow làm reserve
- Scenario planning: Review worst case scenario quarterly
8.4. Risk Mitigation
- Diversify clients: Không để 1 client chiếm >30% revenue
- Advance payment: Negotiate 30-50% advance cho new clients
- Payment terms: Net 15 tốt hơn Net 30
- Vendor terms: Negotiate Net 30-45 với vendors
9. KPIs for Cashflow Management
| KPI | Target | Formula |
|---|---|---|
| Days Sales Outstanding (DSO) | < 30 days | Average 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 days | DSO + Days Inventory - Days Payable |
| Cash Reserve Ratio | > 2x | Cash Balance / Monthly Outflow |
10. Emergency Procedures
10.1. Khi thiếu cashflow đột ngột
Immediate Actions (Day 1-3):
- Call all clients with overdue invoices
- Offer discount for early payment (2-3%)
- Delay all non-critical vendor payments
- 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