Jinja placeholders — Cheatsheet
Jinja placeholders — Cheatsheet
Phần tiêu đề “Jinja placeholders — Cheatsheet”Cheatsheet reference cho pháp chế / Admin tạo template .docx với Jinja placeholders.
Syntax cơ bản
Phần tiêu đề “Syntax cơ bản”Print variable
Phần tiêu đề “Print variable”{{ record.customer_id.name }}{{ record.total_amount }}{{ company.name }}Condition (if / else)
Phần tiêu đề “Condition (if / else)”{% if record.state == 'active' %} HĐ đang hiệu lực{% else %} HĐ chưa active{% endif %}Loop (for)
Phần tiêu đề “Loop (for)”{% for line in record.billing_item_ids %} {{ loop.index }}. {{ line.name }} — {{ line.amount }} VND{% endfor %}Filter
Phần tiêu đề “Filter”{{ record.amount_total | round(0) }} # Làm tròn{{ record.date_start | date_format }} # Format DD/MM/YYYY{{ record.name | upper }} # In hoaObjects available trong template
Phần tiêu đề “Objects available trong template”Wizard truyền context với các keys sau:
| Key | Model | Ví dụ dùng |
|---|---|---|
record | Record đang render | record.name, record.customer_id |
company | env.company hoặc record.company_id | company.name, company.vat |
user | User đang render | user.name |
today | Date hôm nay | {{ today | date_format }} |
today_full | Date full VN | ”Ngày 15 tháng 8 năm 2026” |
Contract (zone.contract) placeholders
Phần tiêu đề “Contract (zone.contract) placeholders”{{ record.name }} # ZC-2026-042{{ record.date_start | date_format }} # 01/08/2026{{ record.date_end | date_format }} # 31/07/2076{{ record.duration_months }} # 600{{ record.total_amount }} # 150,000,000,000{{ record.currency_id.name }} # VND{{ record.project_id.investor_id.name }} # Cty TNHH Apave Vietnam{{ record.project_id.investor_id.vat }} # MST{{ record.project_id.investor_id.street }} # Địa chỉ trụ sở{{ record.project_id.investor_id.city }} # TP HCM{{ record.project_id.investor_id.phone }} # Điện thoại{{ record.project_id.investor_id.x_fax }} # Fax{{ record.project_id.investor_id.x_legal_representative }} # Người đại diện{{ record.project_id.investor_id.x_legal_rep_position }} # Chức vụ (Tổng Giám đốc){{ record.project_id.investor_id.bank_acc_vnd_id.acc_number }} # STK VND{{ record.project_id.investor_id.bank_acc_vnd_id.bank_id.name }} # Ngân hàng{{ record.project_id.investor_id.x_bank_acc_us }} # STK USD{{ record.project_id.investor_id.x_swift_code }} # Swift code{{ record.customer_id.name }} # Cty TNHH Hoa Biết{{ record.customer_id.vat }} # MST{{ record.customer_id.street }} # Trụ sở{{ record.customer_id.city }}{{ record.customer_id.phone }}{{ record.customer_id.x_fax }}{{ record.customer_id.x_legal_representative }} # Cao Thuỳ Dương{{ record.customer_id.x_legal_rep_position }} # Giám đốc{{ record.customer_id.bank_acc_vnd_id.acc_number }}{{ record.customer_id.x_bank_acc_us }}{{ record.customer_id.x_swift_code }}
{{ record.customer_id.x_company_type_label }} # FDI / DDI (Vietnamese label){{ record.customer_id.x_industry_classification }} # Ngành sản xuất{{ record.project_id.name }} # KCN Tân Hoà{{ record.lot_id.code }} # A1-001{{ record.lot_id.area_sqm }} # 5000{{ record.lot_id.lot_type_label }} # Lease land (VN label){{ record.warehouse_id.name }} # Kho W01 (nếu có){{ record.warehouse_id.area_sqm }}{% for item in record.billing_item_ids %}| {{ loop.index }} | {{ item.name }} | {{ item.quantity }} | {{ item.unit_price }} | {{ item.amount }} |{% endfor %}Hoặc render as Word table:
{% for item in record.billing_item_ids %}<tr> <td>{{ loop.index }}</td> <td>{{ item.name }}</td> <td>{{ item.amount }}</td></tr>{% endfor %}{% for m in record.milestone_ids %}- Mốc {{ loop.index }}: {{ m.name }} — {{ m.date_planned | date_format }} — {{ m.amount_pct }}%{% endfor %}Sale Order (sale.order) placeholders
Phần tiêu đề “Sale Order (sale.order) placeholders”{{ record.name }} # S-2026-042{{ record.date_order | date_format }}{{ record.validity_date | date_format }}{{ record.amount_untaxed }}{{ record.amount_tax }}{{ record.amount_total }}{{ record.partner_id.name }} # KH
{% for line in record.order_line %}{{ line.product_id.name }} — {{ line.product_uom_qty }} × {{ line.price_unit }} = {{ line.price_subtotal }}{% endfor %}Deposit Agreement (zone.deposit.agreement)
Phần tiêu đề “Deposit Agreement (zone.deposit.agreement)”{{ record.name }} # DA-2026-018{{ record.partner_id.name }}{{ record.deposit_amount }}{{ record.deposit_paid_amount }}{{ record.date_signed | date_format }}{{ record.date_paid_in_full | date_format }}
{% for tranche in record.deposit_tranche_ids %}Đợt {{ loop.index }}: {{ tranche.date_planned | date_format }} - {{ tranche.amount }} VND{% endfor %}
Customer refund policy: {{ record.customer_refund_policy_label }}Developer refund policy: {{ record.developer_refund_policy_label }}Filters phổ biến
Phần tiêu đề “Filters phổ biến”date_format
Phần tiêu đề “date_format”{{ record.date_start | date_format }} # 15/08/2026{{ record.date_start | date_format('%d/%m/%Y') }} # 15/08/2026 (default){{ record.date_start | date_format('%B %d, %Y') }} # August 15, 2026{{ record.date_start | date_format_vn_long }} # "Ngày 15 tháng 8 năm 2026"currency
Phần tiêu đề “currency”{{ record.total_amount | currency_format }} # "150,000,000,000 ₫"{{ record.total_amount | currency_format('USD') }} # "6,000,000 $"number
Phần tiêu đề “number”{{ 1234567 | number_format }} # "1,234,567"{{ 1234.5678 | number_format(2) }} # "1,234.57"string
Phần tiêu đề “string”{{ record.customer_id.name | upper }} # In HOA{{ record.customer_id.name | lower }} # in thường{{ record.customer_id.name | title }} # Title Case{{ text | truncate(50) }} # Cắt 50 charsconditional / default
Phần tiêu đề “conditional / default”{{ record.x_fax or '(không có)' }} # Fallback{{ record.customer_id.name | default('Khách vô danh') }}Advanced examples
Phần tiêu đề “Advanced examples”Vietnamese day-in-week
Phần tiêu đề “Vietnamese day-in-week”{% set weekday = record.date_start.weekday() %}{% set days = ['Thứ Hai','Thứ Ba','Thứ Tư','Thứ Năm','Thứ Sáu','Thứ Bảy','Chủ Nhật'] %}{{ days[weekday] }}, ngày {{ record.date_start.day }} tháng {{ record.date_start.month }} năm {{ record.date_start.year }}Output: “Thứ Tư, ngày 15 tháng 8 năm 2026”
Số tiền bằng chữ (VN)
Phần tiêu đề “Số tiền bằng chữ (VN)”Cần custom filter to_vietnamese_words (Admin add):
{{ record.total_amount }} đồng ({{ record.total_amount | to_vietnamese_words }})Output: “150,000,000,000 đồng (Một trăm năm mươi tỷ đồng)“
Conditional block cho FDI vs DDI
Phần tiêu đề “Conditional block cho FDI vs DDI”{% if record.customer_id.x_company_type == 'fdi' %} <p>Số IRC: {{ record.customer_id.x_irc_number }}</p> <p>Vốn đầu tư: {{ record.customer_id.x_investment_capital }} USD</p>{% else %} <p>Số ĐKKD: {{ record.customer_id.company_registry }}</p>{% endif %}Nested loop (subline)
Phần tiêu đề “Nested loop (subline)”{% for milestone in record.milestone_ids %}Mốc {{ loop.index }}: {{ milestone.name }} {% for payment in milestone.payment_ids %} - Thanh toán {{ payment.date | date_format }}: {{ payment.amount }} VND {% endfor %}{% endfor %}Debugging placeholders
Phần tiêu đề “Debugging placeholders”1. Render preview thấy {{ some_field }} literal
Phần tiêu đề “1. Render preview thấy {{ some_field }} literal”- Placeholder không được replace → syntax sai (thiếu quote, thừa space, misspell field)
- Verify field tồn tại: mở record → xem field trong Odoo backend
2. Render báo error UndefinedError
Phần tiêu đề “2. Render báo error UndefinedError”- Field không tồn tại trên model → check spell
- Field trên related model → thiếu
.chain (vdrecord.customer_idkhông có.name)
3. Empty output
Phần tiêu đề “3. Empty output”- Field is False / null → dùng
orfallback:{{ value or 'N/A' }} - Related Many2one is empty → check parent first:
{% if record.customer_id %}{{ record.customer_id.name }}{% endif %}
4. Format tiền / date lỗi
Phần tiêu đề “4. Format tiền / date lỗi”- Filter chưa install trong docxtpl → dùng Python built-in:
{{ "%.2f" | format(record.amount) }}
Selection field → Vietnamese label
Phần tiêu đề “Selection field → Vietnamese label”Odoo Selection field lưu key English (vd 'active'). Muốn label VN, dùng _label suffix (Parkone custom):
{{ record.state_label }} # "Đang hoạt động" (not 'active'){{ record.customer_id.x_company_type_label }} # "Nước ngoài (FDI)"{{ record.lot_id.lot_type_label }} # "Đất công nghiệp"Nếu template dùng .state direct → render “active” (English) → không professional.
Cheatsheet compact — bookmark
Phần tiêu đề “Cheatsheet compact — bookmark”Copy vào Word template comment block:
=== JINJA CHEATSHEET ==={{ var }} Print{% if x %}...{% endif %} Condition{% for x in list %}...{% endfor %} Loop{{ x | filter }} Apply filter
Contract fields:- record.name / date_start / total_amount / duration_months- record.customer_id.name / vat / x_legal_representative- record.project_id.investor_id.name / vat / bank_acc_vnd_id.acc_number
Filters:- | date_format → 15/08/2026- | currency_format → "1,000,000 ₫"- | number_format(2) → "1,234.57"- | upper / lower / title- | truncate(50)- | default('N/A')
Vietnamese:- | to_vietnamese_words → "Một triệu đồng"- date_format_vn_long → "Ngày 15 tháng 8 năm 2026"