DHDataHọc
Lý thuyếtBài 2/85 phút đọc+10 XP

Dòng tiền và công nợ

Bạn sẽ học được

  • Vì sao lợi nhuận và tiền mặt không giống nhau.
  • Đọc các khoản mục vốn lưu động: phải thu, phải trả, tồn kho, doanh thu chờ.
  • Dựng dòng tiền hoạt động theo phương pháp gián tiếp bằng SQL.
  • Tính "đốt tiền" và số tháng còn trụ được.
  • Những lỗi khiến báo cáo dòng tiền trông đẹp nhưng công ty vẫn hết tiền.

Khái niệm cốt lõi

Lợi nhuận là số kế toán. Tiền mặt là số trong tài khoản ngân hàng. Hai con số khác nhau vì:

  • Khách mua chịu: đã ghi doanh thu, chưa thu tiền.
  • Trả trước cho nhà cung cấp: đã chi tiền, chưa có chi phí.
  • Khấu hao: chi phí trên báo cáo, không phải tiền ra.
  • Doanh thu chờ: đã thu tiền, chưa được ghi doanh thu.
  • Tồn kho: đã chi tiền, chưa bán.

Một công ty có thể có lãi trên báo cáo và vẫn không đủ tiền trả lương. Đây là lý do dòng tiền phải được phân tích riêng.

Phương pháp gián tiếp

Dòng tiền hoạt động bắt đầu từ lợi nhuận và điều chỉnh:

code
Dòng tiền hoạt động = lợi nhuận
                    + khấu hao (chi phí không bằng tiền)
                    − tăng phải thu
                    − tăng tồn kho
                    + tăng phải trả
                    + tăng doanh thu chờ

Quy tắc nhớ: tài sản tăng thì trừ, nợ phải trả tăng thì cộng. Vì tiền đã bị giữ trong tài sản hoặc được nhà cung cấp cho nợ.

Ví dụ:

KhoảnThay đổiĐiều chỉnh
Lợi nhuận hoạt động—270
Khấu hao60+60
Phải thutăng 150−150
Tồn khotăng 80−80
Phải trảtăng 40+40
Dòng tiền hoạt động140

Lợi nhuận 270 triệu nhưng tiền thực thu từ hoạt động chỉ 140 triệu. Chênh lệch nằm ở vốn lưu động.

Truy vấn phải thu

code
WITH xuat_hoa_don AS (
  SELECT customer_id, SUM(total) AS tong
  FROM invoices
  WHERE issued_at <= CURRENT_DATE
    AND status <> 'cancelled'
  GROUP BY 1
),
thanh_toan AS (
  SELECT customer_id, SUM(amount) AS tong
  FROM payments
  WHERE paid_at <= CURRENT_DATE
  GROUP BY 1
)
SELECT
  COALESCE(i.customer_id, p.customer_id) AS customer_id,
  COALESCE(i.tong, 0) AS da_xuat,
  COALESCE(p.tong, 0) AS da_thu,
  COALESCE(i.tong, 0) - COALESCE(p.tong, 0) AS con_no
FROM xuat_hoa_don i
FULL OUTER JOIN thanh_toan p USING (customer_id);

FULL OUTER JOIN cần thiết: có khách đã trả trước khi có hóa đơn (đặt cọc), và có khách có hóa đơn chưa trả. INNER JOIN sẽ bỏ mất một trong hai.

Kiểm tra tổng: SUM(con_no) phải khớp số dư phải thu trên sổ cái. Lệch nghĩa là có thanh toán không gắn hóa đơn hoặc hóa đơn bị huỷ nhưng vẫn tính.

Doanh thu chờ

Khi khách trả trước cho nhiều tháng, tiền vào ngay nhưng doanh thu ghi dần:

code
SELECT
  SUM(amount) AS da_thu,
  SUM(amount) FILTER (
    WHERE service_start <= CURRENT_DATE
  ) AS da_ghi_nhan_mot_phan,
  SUM(amount) FILTER (
    WHERE service_start > CURRENT_DATE
  ) AS doanh_thu_cho
FROM prepaid_contracts;

Bảng thật cần phân bổ theo ngày, không phải theo hợp đồng — bài sau sẽ làm chi tiết. Ở đây chỉ cần thấy: tiền mặt tăng ngay, doanh thu tăng từ từ.

Đốt tiền và số tháng còn trụ

code
Đốt tiền ròng = tiền chi ra − tiền thu vào (mỗi tháng)
Số tháng còn trụ = tiền mặt hiện có / đốt tiền ròng trung bình

Ví dụ: tiền mặt 1.200 triệu; đốt tiền ròng 200 triệu/tháng → còn 6 tháng.

Ba lưu ý:

  • Dùng trung bình 3 tháng, không dùng một tháng bất thường.
  • Nếu đốt tiền ròng âm (thu nhiều hơn chi), công ty đang tạo tiền — không có khái niệm runway.
  • Runway không tính các khoản thu đột biến chưa chắc xảy ra.

Con số này quan trọng hơn nhiều chỉ số tăng trưởng khi công ty chưa có lãi.

Các khoản nợ phải trả

Phải trả nhà cung cấp là nguồn vốn ngắn hạn. Tăng phải trả cải thiện dòng tiền, nhưng chỉ đến hạn:

code
SELECT
  date_trunc('month', due_date)::date AS thang_den_han,
  SUM(amount) AS phai_tra,
  COUNT(*) AS so_hoa_don
FROM bills
WHERE paid_at IS NULL
GROUP BY 1
ORDER BY 1;

Nếu lịch đến hạn dồn vào một tuần trong khi thu tiền rải đều, công ty có thể mất khả năng thanh toán dù cả năm có lãi. Đây là lý do cần dự báo theo tuần, không chỉ theo tháng.

Lỗi thường gặp

  • Coi doanh thu là tiền thu: bỏ qua phải thu.
  • Bỏ khấu hao: dòng tiền bị đánh giá thấp.
  • Quên doanh thu chờ: tiền vào nhiều nhưng doanh thu ít, báo cáo lệch.
  • Tính runway bằng lợi nhuận: phải dùng tiền mặt thực.
  • Không tách VAT: tiền thu gồm thuế, không phải doanh thu.
  • Bỏ khoản trả trước cho nhà cung cấp: dòng tiền ra bị giấu.
  • Chỉ nhìn tháng: bỏ qua đỉnh thanh toán theo tuần.

Thực hành

  1. Tính dòng tiền hoạt động từ bảng ví dụ.
  2. Viết truy vấn phải thu theo khách với FULL OUTER JOIN.
  3. Tính doanh thu chờ từ hợp đồng trả trước.
  4. Tính runway với tiền mặt và đốt tiền cho trước.
  5. Liệt kê lịch đến hạn phải trả theo tuần trong tháng tới.

Lỗi thường gặp

Triệu chứngNguyên nhânCách sửa
Lãi nhưng hết tiềnPhải thu tăngPhân tích vốn lưu động
Dòng tiền thấp hơn lợi nhuận nhiềuTồn kho hoặc phải thu tăngXem biến động từng khoản
Doanh thu chờ biến mấtKhông tách hợp đồng trả trướcGhi nhận theo kỳ
Runway lạc quanDùng lợi nhuận thay tiền mặtDùng tiền mặt thực
Số dư phải thu không khớpThanh toán không gắn hóa đơnĐối soát theo hóa đơn
Thiếu tiền cuối thángBỏ qua đỉnh phải trảDự báo theo tuần

Tóm tắt

  • Lợi nhuận và tiền mặt khác nhau vì vốn lưu động và chi phí không bằng tiền.
  • Dòng tiền hoạt động = lợi nhuận + khấu hao ± thay đổi vốn lưu động.
  • Phải thu cần FULL OUTER JOIN để không bỏ sót đặt cọc.
  • Doanh thu chờ là tiền đã thu nhưng chưa ghi doanh thu.
  • Runway tính từ tiền mặt và đốt tiền ròng, không từ lợi nhuận.

Dùng ← → để chuyển bài