invoicemgmt-1.0.0/templates/node--invoice--pdf.html.twig
templates/node--invoice--pdf.html.twig
{#
/**
* @file
* Entity Print template for invoice nodes (PDF generation).
*
* Available variables:
* - content: Content of the entity being printed
* - entity: The entity being printed
*/
#}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Invoice {{ entity.field_invoice_number.value }}</title>
<style>
{{ source('@invoicemgmt/css/invoice-styles.css') }}
/* Dynamic color variables */
:root {
--primary-color: {{ invoice_data.primary_color ?: '#667eea' }};
--secondary-color: {{ invoice_data.secondary_color ?: '#764ba2' }};
--accent-color: {{ invoice_data.accent_color ?: '#4299e1' }};
}
.invoice-header {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%) !important;
}
.items-total {
border-left-color: var(--accent-color) !important;
}
.invoice-notes,
.invoice-terms,
.payment-info {
border-left-color: var(--accent-color) !important;
}
/* PDF-specific overrides */
body {
margin: 0;
padding: 0;
font-family: 'Segoe UI', Arial, sans-serif;
}
.invoice-actions {
display: none !important;
}
.invoice-container {
max-width: none;
margin: 0;
padding: 20px;
box-shadow: none;
border-radius: 0;
}
.invoice-header {
margin: -20px -20px 30px -20px;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 0;
}
/* Ensure proper page breaks */
.invoice-items,
.invoice-totals {
page-break-inside: avoid;
}
.invoice-footer {
page-break-inside: avoid;
margin-top: 30px;
}
</style>
</head>
<body>
{% set invoice_data = {
'seller_name': config('invoicemgmt.settings').get('seller_name'),
'seller_address': config('invoicemgmt.settings').get('seller_address'),
'terms_conditions': config('invoicemgmt.settings').get('terms_conditions'),
'bank_details': config('invoicemgmt.settings').get('bank_details'),
'currency': config('invoicemgmt.settings').get('currency') ?: 'GBP',
'footer_text': config('invoicemgmt.settings').get('footer_text') ?: 'Thank you for your business!',
} %}
{% set currency_symbols = {
'GBP': '£',
'USD': '$',
'AED': 'د.إ',
'INR': '₹',
'EUR': '€',
} %}
{% set invoice_data = invoice_data|merge({'currency_symbol': currency_symbols[invoice_data.currency] ?: invoice_data.currency}) %}
{% if config('invoicemgmt.settings').get('logo') %}
{% set logo_file = file_load(config('invoicemgmt.settings').get('logo')) %}
{% if logo_file %}
{% set invoice_data = invoice_data|merge({
'logo': {
'url': file_url(logo_file.uri.value),
'alt': invoice_data.seller_name,
}
}) %}
{% endif %}
{% endif %}
<div class="invoice-container">
<div class="invoice-header">
<div class="invoice-header-left">
{% if invoice_data.logo %}
<div class="company-logo">
<img src="{{ invoice_data.logo.url }}" alt="{{ invoice_data.seller_name }}" />
</div>
{% endif %}
<div class="company-info">
<h1 class="company-name">{{ invoice_data.seller_name }}</h1>
<div class="company-address">{{ invoice_data.seller_address|nl2br }}</div>
</div>
</div>
<div class="invoice-header-right">
<div class="invoice-title">
<h2>INVOICE</h2>
</div>
<div class="invoice-meta">
<div class="invoice-number">
<strong>Invoice #:</strong> {{ entity.field_invoice_number.value }}
</div>
<div class="invoice-date">
<strong>Date:</strong> {{ entity.field_invoice_date.value|date('M d, Y')|default(entity.created.value|date('M d, Y')) }}
</div>
<div class="due-date">
<strong>Due Date:</strong> {{ entity.field_due_date.value|date('M d, Y')|default(entity.created.value|date('M d, Y')) }}
</div>
</div>
</div>
</div>
<div class="invoice-parties">
<div class="bill-to">
<h3>Bill To:</h3>
{% if entity.field_client.entity %}
{% set client = entity.field_client.entity %}
<div class="client-info">
<div class="client-name">{{ client.title.value }}</div>
{% if client.field_client_email.value %}
<div class="client-email">{{ client.field_client_email.value }}</div>
{% endif %}
{% if client.field_client_phone.value %}
<div class="client-phone">{{ client.field_client_phone.value }}</div>
{% endif %}
{% if client.field_client_address.value %}
<div class="client-address">{{ client.field_client_address.value|nl2br }}</div>
{% endif %}
</div>
{% endif %}
</div>
<div class="invoice-status">
{% if entity.field_invoice_status.value %}
<div class="status-badge status-{{ entity.field_invoice_status.value|lower|replace(' ', '-') }}">
{{ entity.field_invoice_status.value }}
</div>
{% endif %}
</div>
</div>
{% if entity.field_items %}
{% set invoice_items = [] %}
{% set items_total = 0 %}
{% for item in entity.field_items.referencedEntities %}
{% if item.bundle == 'invoice_item' %}
{% set item_name = item.field_item_name.entity ? item.field_item_name.entity.name.value : '' %}
{% set item_amount = item.field_amount.value|number_format(2) %}
{% set invoice_items = invoice_items|merge([{
'field_item_name': item_name,
'field_amount': item_amount
}]) %}
{% set items_total = items_total + item.field_amount.value %}
{% endif %}
{% endfor %}
{% if invoice_items %}
<div class="invoice-items">
<table class="items-table">
<thead>
<tr>
<th class="item-serial">#</th>
<th class="item-description">Item Description</th>
<th class="item-amount">Amount</th>
</tr>
</thead>
<tbody>
{% for item in invoice_items %}
<tr>
<td class="item-serial">{{ loop.index }}</td>
<td class="item-description">{{ item.field_item_name }}</td>
<td class="item-amount">{{ invoice_data.currency_symbol }}{{ item.field_amount }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="items-total">
<div class="items-total-row">
<span class="items-total-label">Items Total:</span>
<span class="items-total-value">{{ invoice_data.currency_symbol }}{{ items_total|number_format(2) }}</span>
</div>
</div>
</div>
{% endif %}
{% endif %}
<div class="invoice-totals">
<div class="totals-section">
{% if entity.field_subtotal.value %}
<div class="total-row">
<span class="total-label">Subtotal:</span>
<span class="total-value">{{ invoice_data.currency_symbol }}{{ entity.field_subtotal.value|number_format(2) }}</span>
</div>
{% endif %}
{% if entity.field_tax_amount.value %}
<div class="total-row">
<span class="total-label">Tax:</span>
<span class="total-value">{{ invoice_data.currency_symbol }}{{ entity.field_tax_amount.value|number_format(2) }}</span>
</div>
{% endif %}
{% if entity.field_discount.value %}
<div class="total-row">
<span class="total-label">Discount:</span>
<span class="total-value">-{{ invoice_data.currency_symbol }}{{ entity.field_discount.value|number_format(2) }}</span>
</div>
{% endif %}
{% if entity.field_total_amount.value %}
<div class="total-row total-final">
<span class="total-label">Total Amount:</span>
<span class="total-value">{{ invoice_data.currency_symbol }}{{ entity.field_total_amount.value|number_format(2) }}</span>
</div>
{% endif %}
</div>
</div>
{% if entity.field_invoice_notes.value %}
<div class="invoice-notes">
<h4>Notes:</h4>
<div class="notes-content">
{{ entity.field_invoice_notes.value|nl2br }}
</div>
</div>
{% endif %}
{% if invoice_data.terms_conditions %}
<div class="invoice-terms">
<h4>Terms & Conditions:</h4>
<div class="terms-content">
{{ invoice_data.terms_conditions|nl2br }}
</div>
</div>
{% endif %}
{% if invoice_data.bank_details %}
<div class="payment-info">
<h4>Payment Information:</h4>
<div class="bank-details">
{{ invoice_data.bank_details|nl2br }}
</div>
</div>
{% endif %}
<div class="invoice-footer">
<p class="thank-you">{{ invoice_data.footer_text|nl2br }}</p>
<div class="invoice-timestamp">
Generated on {{ "now"|date('M d, Y \\a\\t g:i A') }}
</div>
</div>
</div>
</body>
</html>