PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.0
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.0
2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.2 All 57 releases
easy-invoice / templates / invoice-templates / minimal.php

minimal.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.4.0, at templates/invoice-templates/minimal.php

562 lines 20.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Minimal Template - Clean & Simple Design
4 * Minimal, clean, and simple invoice template
5 */
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit;
9 }
10 $text_settings = \EasyInvoice\Helpers\TemplateTextHelper::forDocument(\EasyInvoice\Helpers\TemplateTextHelper::getInvoiceTextSettings(), $invoice);
11 $ei_is_credit_note = \EasyInvoice\Helpers\TemplateTextHelper::isCreditNote($invoice);
12 $company_info = \EasyInvoice\Helpers\TemplateTextHelper::getCompanyInfo();
13 ?>
14 <style>
15 /* Minimal Template - Clean & Simple Design */
16 :root {
17 --primary-color: #374151;
18 --primary-light: #6b7280;
19 --primary-dark: #1f2937;
20 --secondary-color: #9ca3af;
21 --accent-color: #3b82f6;
22 --success-color: #10b981;
23 --warning-color: #f59e0b;
24 --error-color: #ef4444;
25 --text-primary: #111827;
26 --text-secondary: #6b7280;
27 --text-muted: #9ca3af;
28 --border-color: #d1d5db;
29 --border-light: #e5e7eb;
30 --background-primary: #ffffff;
31 --background-secondary: #f9fafb;
32 --background-accent: #f3f4f6;
33
34 --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
35 --font-family-heading: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
36
37 --font-size-xs: 0.75rem;
38 --font-size-sm: 0.875rem;
39 --font-size-base: 1rem;
40 --font-size-lg: 1.125rem;
41 --font-size-xl: 1.25rem;
42 --font-size-2xl: 1.5rem;
43 --font-size-3xl: 1.875rem;
44 --font-size-4xl: 2.25rem;
45
46 --spacing-1: 0.25rem;
47 --spacing-2: 0.5rem;
48 --spacing-3: 0.75rem;
49 --spacing-4: 1rem;
50 --spacing-5: 1.25rem;
51 --spacing-6: 1.5rem;
52 --spacing-8: 2rem;
53 --spacing-10: 2.5rem;
54 --spacing-12: 3rem;
55 --spacing-16: 4rem;
56 --spacing-20: 5rem;
57
58 --radius-sm: 0.25rem;
59 --radius-md: 0.375rem;
60 --radius-lg: 0.5rem;
61 --radius-xl: 0.75rem;
62 --radius-2xl: 1rem;
63
64 --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
65 --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
66 --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
67 --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
68 }
69
70 .template-minimal {
71 font-family: var(--font-family);
72 background: var(--background-primary);
73 color: var(--text-primary);
74 max-width: 800px;
75 margin: 0 auto;
76 padding: var(--spacing-8);
77 line-height: 1.6;
78 }
79
80 /* Header Section */
81 .template-minimal .invoice-header {
82 display: flex;
83 justify-content: space-between;
84 align-items: flex-start;
85 margin-bottom: var(--spacing-12);
86 padding-bottom: var(--spacing-8);
87 border-bottom: 1px solid var(--border-light);
88 }
89
90 .template-minimal .company-info {
91 flex: 1;
92 }
93
94 .template-minimal .company-logo {
95 margin-bottom: 0;
96 }
97
98 .template-minimal .logo-image {
99 max-height: 60px;
100 max-width: 200px;
101 object-fit: contain;
102 filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
103 }
104
105 .template-minimal .company-name {
106 font-family: var(--font-family-heading);
107 font-size: var(--font-size-2xl);
108 font-weight: 700;
109 color: var(--text-primary);
110 margin-bottom: var(--spacing-3);
111 line-height: 1.2;
112 }
113
114 .template-minimal .company-details {
115 color: var(--text-secondary);
116 font-size: var(--font-size-sm);
117 line-height: 1.5;
118 }
119
120 .template-minimal .invoice-meta {
121 text-align: right;
122 min-width: 200px;
123 }
124
125 .template-minimal .invoice-title {
126 font-family: var(--font-family-heading);
127 font-size: var(--font-size-xl);
128 font-weight: 600;
129 color: var(--text-primary);
130 margin-bottom: var(--spacing-4);
131 }
132
133 .template-minimal .meta-item {
134 display: flex;
135 justify-content: space-between;
136 align-items: center;
137 margin-bottom: var(--spacing-2);
138 padding-bottom: var(--spacing-2);
139 border-bottom: 1px solid var(--border-light);
140 }
141
142 .template-minimal .meta-item:last-child {
143 margin-bottom: 0;
144 padding-bottom: 0;
145 border-bottom: none;
146 }
147
148 .template-minimal .meta-label {
149 font-size: var(--font-size-sm);
150 color: var(--text-secondary);
151 font-weight: 400;
152 }
153
154 .template-minimal .meta-value {
155 font-size: var(--font-size-sm);
156 color: var(--text-primary);
157 font-weight: 500;
158 }
159
160 /* Address Section */
161 .template-minimal .address-section {
162 display: grid;
163 grid-template-columns: 1fr 1fr;
164 gap: var(--spacing-8);
165 margin-bottom: var(--spacing-12);
166 }
167
168 .template-minimal .address-block h2 {
169 font-family: var(--font-family-heading);
170 font-size: var(--font-size-base);
171 font-weight: 600;
172 color: var(--text-primary);
173 margin-bottom: var(--spacing-3);
174 }
175
176 .template-minimal .client-name {
177 font-weight: 600;
178 color: var(--text-primary);
179 font-size: var(--font-size-base);
180 margin-bottom: var(--spacing-2);
181 }
182
183 .template-minimal .address-content {
184 color: var(--text-secondary);
185 font-size: var(--font-size-sm);
186 line-height: 1.5;
187 }
188
189 /* Invoice Items Table */
190 .template-minimal .invoice-items {
191 width: 100%;
192 border-collapse: collapse;
193 margin-bottom: var(--spacing-12);
194 background: var(--background-primary);
195 border: 1px solid var(--border-color);
196 }
197
198 .template-minimal .invoice-items th {
199 background: var(--background-secondary);
200 color: var(--text-primary);
201 font-weight: 600;
202 text-align: left;
203 padding: var(--spacing-3) var(--spacing-4);
204 font-size: var(--font-size-sm);
205 border-bottom: 1px solid var(--border-color);
206 }
207
208 .template-minimal .invoice-items td {
209 padding: var(--spacing-3) var(--spacing-4);
210 border-bottom: 1px solid var(--border-light);
211 vertical-align: top;
212 }
213
214 .template-minimal .invoice-items tr:last-child td {
215 border-bottom: none;
216 }
217
218 .template-minimal .item-name .item-title {
219 font-weight: 500;
220 color: var(--text-primary);
221 margin-bottom: var(--spacing-1);
222 }
223
224 .template-minimal .item-description {
225 color: var(--text-muted);
226 font-size: var(--font-size-sm);
227 line-height: 1.4;
228 font-weight: normal;
229 }
230
231 .template-minimal .item-quantity,
232 .template-minimal .item-price,
233 .template-minimal .item-total {
234 text-align: right;
235 font-weight: 400;
236 color: var(--text-primary);
237 }
238
239 /* Invoice Totals */
240 .template-minimal .invoice-totals {
241 margin-left: auto;
242 width: 300px;
243 background: var(--background-secondary);
244 padding: var(--spacing-6);
245 border: 1px solid var(--border-color);
246 }
247
248 .template-minimal .invoice-total-row {
249 display: flex;
250 justify-content: space-between;
251 align-items: center;
252 padding: var(--spacing-2) 0;
253 border-bottom: 1px solid var(--border-light);
254 }
255
256 .template-minimal .invoice-total-row:last-child {
257 border-bottom: none;
258 }
259
260 .template-minimal .invoice-total-label {
261 font-weight: 400;
262 color: var(--text-secondary);
263 }
264
265 .template-minimal .invoice-total-value {
266 font-weight: 600;
267 color: var(--text-primary);
268 }
269
270 .template-minimal .invoice-totals .invoice-grand-total {
271 font-size: var(--font-size-lg);
272 font-weight: 700;
273 color: var(--text-primary);
274 border-top: 2px solid var(--border-color);
275 padding-top: var(--spacing-3);
276 margin-top: var(--spacing-3);
277 }
278
279 /* Notes Section */
280 .template-minimal .invoice-notes {
281 margin-top: var(--spacing-8);
282 padding: var(--spacing-6);
283 background: var(--background-secondary);
284 border-radius: var(--radius-lg);
285 border: 1px solid var(--border-color);
286 }
287
288 .template-minimal .invoice-notes h3 {
289 font-family: var(--font-family-heading);
290 font-size: var(--font-size-lg);
291 font-weight: 600;
292 color: var(--text-primary);
293 margin-bottom: var(--spacing-3);
294 border-bottom: 1px solid var(--border-color);
295 padding-bottom: var(--spacing-2);
296 }
297
298 .template-minimal .notes-content {
299 color: var(--text-secondary);
300 font-size: var(--font-size-sm);
301 line-height: 1.6;
302 }
303
304 .template-minimal .invoice-terms {
305 margin-top: var(--spacing-8);
306 padding: var(--spacing-6);
307 background: var(--background-secondary);
308 border-radius: var(--radius-lg);
309 border: 1px solid var(--border-color);
310 }
311
312 .template-minimal .invoice-terms h3 {
313 font-family: var(--font-family-heading);
314 font-size: var(--font-size-lg);
315 font-weight: 600;
316 color: var(--text-primary);
317 margin-bottom: var(--spacing-3);
318 border-bottom: 1px solid var(--border-color);
319 padding-bottom: var(--spacing-2);
320 }
321
322 .template-minimal .terms-content {
323 color: var(--text-secondary);
324 font-size: var(--font-size-sm);
325 line-height: 1.6;
326 }
327
328 .template-minimal .invoice-footer {
329 margin-top: var(--spacing-8);
330 padding-top: var(--spacing-6);
331 border-top: 2px solid var(--border-light);
332 text-align: center;
333 color: var(--text-secondary);
334 font-size: var(--font-size-sm);
335 }
336
337 /* Footer */
338 .template-minimal .invoice-footer {
339 margin-top: var(--spacing-12);
340 padding: var(--spacing-6);
341 text-align: center;
342 background: var(--background-secondary);
343 border: 1px solid var(--border-color);
344 }
345
346 .template-minimal .invoice-footer p {
347 margin: 0;
348 color: var(--text-secondary);
349 font-size: var(--font-size-sm);
350 }
351
352 /* Responsive Design */
353 @media (max-width: 768px) {
354 .template-minimal {
355 padding: var(--spacing-4);
356 }
357
358 .template-minimal .invoice-header {
359 flex-direction: column;
360 gap: var(--spacing-6);
361 }
362
363 .template-minimal .invoice-meta {
364 text-align: left;
365 min-width: auto;
366 }
367
368 .template-minimal .address-section {
369 grid-template-columns: 1fr;
370 gap: var(--spacing-6);
371 }
372
373 .template-minimal .invoice-totals {
374 width: 100%;
375 }
376 }
377
378 /* Shared polish: numbers line up, numeric headings sit over their figures. */
379 .template-minimal .invoice-items th + th { text-align: right; }
380 .template-minimal .invoice-items .item-quantity,
381 .template-minimal .invoice-items .item-price,
382 .template-minimal .invoice-items .item-adjust,
383 .template-minimal .invoice-items .item-total,
384 .template-minimal .invoice-total-value { font-variant-numeric: tabular-nums; white-space: nowrap; }
385 .template-minimal .meta-value { white-space: nowrap; }
386 .template-minimal .invoice-items .item-adjust { text-align: right; }
387 .template-minimal .client-contact { font-weight: 500; margin-bottom: 0.15em; }
388 .template-minimal .client-tax-number,
389 .template-minimal .company-tax-number { margin-top: 0.35em; }
390 .template-minimal .invoice-items .item-description { white-space: pre-line; }
391 .template-minimal .document-kind { display: block; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-muted, #8a8a8a); font-family: var(--font-family-body, inherit); font-style: normal; margin-bottom: 0.3em; line-height: 1.2; }
392
393 /* Minimal: hairlines only — no filled panels anywhere. */
394 .template-minimal .invoice-header { margin-bottom: var(--spacing-8); padding-bottom: var(--spacing-6); border-bottom: 1px solid var(--border-color); }
395 .template-minimal .address-section { margin-bottom: var(--spacing-8); }
396 .template-minimal .address-block h2 { font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-muted); font-weight: 600; margin-bottom: var(--spacing-2); }
397 .template-minimal .invoice-items { border: 0; margin-bottom: var(--spacing-6); }
398 .template-minimal .invoice-items th { background: transparent; color: var(--text-muted); font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.12em; padding: var(--spacing-2) var(--spacing-3); border-bottom: 1px solid var(--text-primary); }
399 .template-minimal .invoice-items td { padding: var(--spacing-4) var(--spacing-3); }
400 .template-minimal .invoice-items th:first-child, .template-minimal .invoice-items td:first-child { padding-left: 0; }
401 .template-minimal .invoice-items th:last-child, .template-minimal .invoice-items td:last-child { padding-right: 0; }
402 .template-minimal .invoice-totals { background: transparent; border: 0; padding: 0; width: 320px; }
403 .template-minimal .invoice-total-row { padding: var(--spacing-2) 0; border-bottom: 1px solid var(--border-light); }
404 .template-minimal .invoice-totals .invoice-grand-total { border-top: 1px solid var(--text-primary); border-bottom: 0; margin-top: var(--spacing-1); padding-top: var(--spacing-3); font-size: var(--font-size-lg); }
405 .template-minimal .invoice-totals .invoice-grand-total .invoice-total-value { font-size: var(--font-size-xl); }
406 .template-minimal .invoice-notes, .template-minimal .invoice-terms { background: transparent; border: 0; border-top: 1px solid var(--border-light); border-radius: 0; padding: var(--spacing-5) 0 0; margin-top: var(--spacing-6); }
407 .template-minimal .invoice-notes h3, .template-minimal .invoice-terms h3 { font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-muted); font-weight: 600; margin-bottom: var(--spacing-2); border: 0; padding: 0; }
408 .template-minimal .invoice-footer { background: transparent; border: 0; border-top: 1px solid var(--border-light); padding: var(--spacing-4) 0 0; margin-top: var(--spacing-8); color: var(--text-muted); font-size: var(--font-size-sm); }
409 .template-minimal .invoice-totals .invoice-paid-row .invoice-total-value { color: var(--success-color, #047857); }
410 .template-minimal .invoice-totals .invoice-balance-due { font-weight: 700; }
411 .template-minimal .invoice-totals .invoice-balance-due .invoice-total-label { color: inherit; font-weight: 700; }
412 .template-minimal .meta-amount-due .meta-value { font-weight: 700; font-size: 1.08em; }
413 </style>
414
415 <div class="template template-minimal">
416 <div class="invoice-header">
417 <div class="company-info">
418 <?php if (!empty($company_info['logo'])): ?>
419 <div class="company-logo">
420 <img src="<?php echo esc_url($company_info['logo']); ?>" alt="<?php echo esc_attr($company_info['name']); ?>" class="logo-image" onerror="this.parentNode.parentNode.removeChild(this.parentNode)">
421 </div>
422 <?php endif; ?>
423 <div class="company-name"><?php echo esc_html($company_info['name']); ?></div>
424 <div class="company-details">
425 <?php echo wp_kses_post(\EasyInvoice\Helpers\TemplateTextHelper::generateFromSection($company_info, false, 'details-only')); ?>
426 </div>
427 </div>
428
429 <div class="invoice-meta">
430 <?php $ei_kind = \EasyInvoice\Helpers\TemplateTextHelper::documentKind($invoice); $ei_title = trim((string) $invoice->getTitle()); ?>
431 <div class="invoice-title"><?php if ('' !== $ei_title && 0 !== strcasecmp($ei_title, $ei_kind)) : ?><span class="document-kind"><?php echo esc_html($ei_kind); ?></span><?php endif; ?><?php echo esc_html('' !== $ei_title ? $ei_title : $ei_kind); ?></div>
432 <div class="meta-item">
433 <span class="meta-label"><?php echo esc_html($text_settings['invoice_number']); ?></span>
434 <span class="meta-value"><?php echo esc_html($invoice->getNumber()); ?></span>
435 </div>
436 <div class="meta-item">
437 <span class="meta-label"><?php echo esc_html($text_settings['invoice_date']); ?></span>
438 <span class="meta-value"><?php echo esc_html(\EasyInvoice\Controllers\SettingsController::formatDate($invoice->getIssueDate())); ?></span>
439 </div>
440 <?php if (empty($ei_is_credit_note)) : ?>
441 <div class="meta-item">
442 <span class="meta-label"><?php echo esc_html($text_settings['due_date']); ?></span>
443 <span class="meta-value"><?php echo esc_html(\EasyInvoice\Controllers\SettingsController::formatDate($invoice->getDueDate())); ?></span>
444 </div>
445 <?php endif; ?>
446 <?php if (empty($ei_is_credit_note)) : ?>
447 <div class="meta-item meta-amount-due">
448 <span class="meta-label"><?php echo esc_html($text_settings['total_due']); ?></span>
449 <span class="meta-value"><?php echo esc_html($formatter->format(\EasyInvoice\Helpers\TemplateTextHelper::amountDue($invoice))); ?></span>
450 </div>
451 <?php endif; ?>
452 </div>
453 </div>
454
455 <?php $ei_client_html = \EasyInvoice\Helpers\TemplateTextHelper::generateClientBlock($invoice); if ('' !== $ei_client_html) : ?>
456 <div class="address-section">
457 <div class="address-block">
458 <h2><?php echo esc_html($text_settings['to']); ?></h2>
459 <div class="address-content">
460 <?php echo wp_kses_post($ei_client_html); ?>
461 </div>
462 </div>
463 </div>
464 <?php endif; ?>
465
466 <?php
467 // The adjustment column appears only when at least one line uses it.
468 $ei_show_adjust = \EasyInvoice\Controllers\SettingsController::shouldShowInvoiceAdjustField();
469 if ($ei_show_adjust) {
470 $ei_show_adjust = false;
471 foreach ($invoice->getItems() as $ei_item) {
472 if ((float) $ei_item->getAdjustPercentage() != 0.0) { $ei_show_adjust = true; break; }
473 }
474 }
475 ?>
476 <table class="invoice-items">
477 <thead>
478 <tr>
479 <th><?php echo esc_html($text_settings['service']); ?></th>
480 <th><?php echo esc_html($text_settings['qty']); ?></th>
481 <th><?php echo esc_html($text_settings['rate_price']); ?></th>
482 <?php if ($ei_show_adjust): ?>
483 <th><?php echo esc_html($text_settings['adjust']); ?> (%)</th>
484 <?php endif; ?>
485 <th><?php echo esc_html($text_settings['line_total'] ?? $text_settings['total']); ?></th>
486 </tr>
487 </thead>
488 <tbody>
489 <?php if (!$invoice->getItems()) : ?>
490 <tr class="no-items"><td colspan="<?php echo $ei_show_adjust ? 5 : 4; ?>" style="text-align:center;color:#9ca3af;padding:18px;"><?php esc_html_e('No items yet.', 'easy-invoice'); ?></td></tr>
491 <?php endif; ?>
492 <?php foreach ($invoice->getItems() as $item): ?>
493 <tr>
494 <td class="item-name">
495 <div class="item-title"><?php echo esc_html($item->getName()); ?></div>
496 <?php if ($item->getDescription()): ?>
497 <div class="item-description"><?php echo esc_html($item->getDescription()); ?></div>
498 <?php endif; ?>
499 </td>
500 <td class="item-quantity"><?php echo esc_html($item->getQuantity() ?: '0'); ?></td>
501 <td class="item-price"><?php echo esc_html($formatter->format($item->getPrice())); ?></td>
502 <?php if ($ei_show_adjust): ?>
503 <td class="item-adjust"><?php
504 $adjust_percentage = $item->getAdjustPercentage();
505 if ($adjust_percentage != 0) {
506 echo esc_html($adjust_percentage > 0 ? '+' : '') . esc_html($adjust_percentage) . '%';
507 } else {
508 echo esc_html__('—', 'easy-invoice');
509 }
510 ?></td>
511 <?php endif; ?>
512 <td class="item-total"><?php echo esc_html($formatter->format($item->getAmount())); ?></td>
513 </tr>
514 <?php endforeach; ?>
515 </tbody>
516 </table>
517
518 <div class="invoice-totals">
519 <?php echo wp_kses_post(\EasyInvoice\Helpers\TemplateTextHelper::generateTotalsSection($invoice, $text_settings, $formatter, 'invoice')); ?>
520 </div>
521
522 <?php if ($invoice->getNotes()): ?>
523 <div class="invoice-notes">
524 <h3><?php esc_html_e('Notes', 'easy-invoice'); ?></h3>
525 <div class="notes-content">
526 <?php echo wp_kses_post($invoice->getNotes() ?: ''); ?>
527 </div>
528 </div>
529 <?php endif; ?>
530
531 <?php
532 $terms_conditions = empty($ei_is_credit_note) ? ($invoice->getTerms() ?: \EasyInvoice\Controllers\SettingsController::getInvoiceTermsConditions()) : '';
533 if ($terms_conditions):
534 ?>
535 <div class="invoice-terms">
536 <h3><?php esc_html_e('Terms & Conditions', 'easy-invoice'); ?></h3>
537 <div class="terms-content">
538 <?php echo wp_kses_post($terms_conditions); ?>
539 </div>
540 </div>
541 <?php endif; ?>
542
543 <?php
544 /**
545 * Fires inside the document card, after notes and terms and before the
546 * footer text: attachments, the signature block, e-invoicing notes. Being
547 * inside the card, it is part of what "Download as PDF" captures.
548 *
549 * @param object $document The invoice model.
550 * @param string $type 'invoice'.
551 */
552 do_action('easy_invoice_document_body_after', $invoice, 'invoice');
553
554 $ei_footer_text = \EasyInvoice\Helpers\TemplateTextHelper::footerText($invoice, 'invoice');
555 if ('' !== trim(wp_strip_all_tags((string) $ei_footer_text))) :
556 ?>
557 <div class="invoice-footer">
558 <p><?php echo wp_kses_post($ei_footer_text); ?></p>
559 </div>
560 <?php endif; ?>
561 </div>
562