PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.4
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.4
2.4.3 2.4.4 2.4.2 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 All 60 releases
← All changes | templates/quote-templates/minimal.php +82 -27 2.3.7 → 2.4.4 View file →
@@ -3,8 +3,11 @@
3 3 * Minimal Quote Template - Clean & Simple Design
4 4 * Minimal, clean, and simple quote template
5 5 */
6 6
7 +if ( ! defined( 'ABSPATH' ) ) {
8 + exit;
9 +}
7 10 $text_settings = \EasyInvoice\Helpers\TemplateTextHelper::getQuoteTextSettings();
8 11 $company_info = \EasyInvoice\Helpers\TemplateTextHelper::getCompanyInfo();
9 12 ?>
10 13 <style>
@@ -273,9 +276,9 @@
273 276 font-weight: 600;
274 277 color: var(--text-primary);
275 278 }
276 279
277 -.template-minimal .quote-grand-total {
280 +.template-minimal .quote-totals .quote-grand-total {
278 281 font-size: var(--font-size-lg);
279 282 font-weight: 700;
280 283 color: var(--text-primary);
281 284 border-top: 2px solid var(--border-color);
@@ -366,26 +369,59 @@
366 369 .template-minimal .quote-totals {
367 370 width: 100%;
368 371 }
369 372 }
373 +
374 +/* Shared polish: numbers line up, numeric headings sit over their figures. */
375 +.template-minimal .quote-items th + th { text-align: right; }
376 +.template-minimal .quote-items .item-quantity,
377 +.template-minimal .quote-items .item-price,
378 +.template-minimal .quote-items .item-adjust,
379 +.template-minimal .quote-items .item-total,
380 +.template-minimal .quote-total-value { font-variant-numeric: tabular-nums; white-space: nowrap; }
381 +.template-minimal .meta-value { white-space: nowrap; }
382 +.template-minimal .quote-items .item-adjust { text-align: right; }
383 +.template-minimal .client-contact { font-weight: 500; margin-bottom: 0.15em; }
384 +.template-minimal .client-tax-number,
385 +.template-minimal .company-tax-number { margin-top: 0.35em; }
386 +.template-minimal .quote-items .item-description { white-space: pre-line; }
387 +.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; }
388 +
389 +/* Minimal: hairlines only — no filled panels anywhere. */
390 +.template-minimal .quote-header { margin-bottom: var(--spacing-8); padding-bottom: var(--spacing-6); border-bottom: 1px solid var(--border-color); }
391 +.template-minimal .address-section { margin-bottom: var(--spacing-8); }
392 +.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); }
393 +.template-minimal .quote-items { border: 0; margin-bottom: var(--spacing-6); }
394 +.template-minimal .quote-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); }
395 +.template-minimal .quote-items td { padding: var(--spacing-4) var(--spacing-3); }
396 +.template-minimal .quote-items th:first-child, .template-minimal .quote-items td:first-child { padding-left: 0; }
397 +.template-minimal .quote-items th:last-child, .template-minimal .quote-items td:last-child { padding-right: 0; }
398 +.template-minimal .quote-totals { background: transparent; border: 0; padding: 0; width: 320px; }
399 +.template-minimal .quote-total-row { padding: var(--spacing-2) 0; border-bottom: 1px solid var(--border-light); }
400 +.template-minimal .quote-totals .quote-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); }
401 +.template-minimal .quote-totals .quote-grand-total .quote-total-value { font-size: var(--font-size-xl); }
402 +.template-minimal .quote-notes, .template-minimal .quote-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); }
403 +.template-minimal .quote-notes h3, .template-minimal .quote-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; }
404 +.template-minimal .quote-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); }
370 405 </style>
371 406
372 407 <div class="template template-minimal">
373 408 <div class="quote-header">
374 409 <div class="company-info">
410 + <?php if (!empty($company_info['logo'])): ?>
375 411 <div class="company-logo">
376 - <?php if (!empty($company_info['logo'])): ?>
377 - <img src="<?php echo esc_url($company_info['logo']); ?>" alt="<?php echo esc_attr($company_info['name']); ?>" class="logo-image">
378 - <?php endif; ?>
412 + <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)">
379 413 </div>
414 + <?php endif; ?>
380 415 <div class="company-name"><?php echo esc_html($company_info['name']); ?></div>
381 416 <div class="company-details">
382 - <?php echo \EasyInvoice\Helpers\TemplateTextHelper::generateFromSection($company_info, false, 'details-only'); ?>
417 + <?php echo wp_kses_post(\EasyInvoice\Helpers\TemplateTextHelper::generateFromSection($company_info, false, 'details-only')); ?>
383 418 </div>
384 419 </div>
385 420
386 421 <div class="quote-meta">
387 - <div class="quote-title"><?php echo esc_html($quote->getTitle() ?: __('Quote', 'easy-invoice')); ?></div>
422 + <?php $ei_kind = \EasyInvoice\Controllers\SettingsController::getTextQuote(); $ei_title = trim((string) $quote->getTitle()); ?>
423 + <div class="quote-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>
388 424 <div class="meta-item">
389 425 <span class="meta-label"><?php echo esc_html($text_settings['quote_number']); ?></span>
390 426 <span class="meta-value"><?php echo esc_html($quote->getNumber()); ?></span>
391 427 </div>
@@ -399,22 +435,18 @@
399 435 </div>
400 436 </div>
401 437 </div>
402 438
439 + <?php $ei_client_html = \EasyInvoice\Helpers\TemplateTextHelper::generateClientBlock($quote); if ('' !== $ei_client_html) : ?>
403 440 <div class="address-section">
404 441 <div class="address-block">
405 442 <h2><?php echo esc_html($text_settings['to']); ?></h2>
406 443 <div class="address-content">
407 - <div class="client-name"><?php echo esc_html($quote->getCustomerName()); ?></div>
408 - <?php if ($quote->getCustomerAddress()): ?>
409 - <?php echo nl2br(esc_html($quote->getCustomerAddress())); ?><br>
410 - <?php endif; ?>
411 - <?php if ($quote->getCustomerEmail()): ?>
412 - <?php echo esc_html($quote->getCustomerEmail()); ?><br>
413 - <?php endif; ?>
444 + <?php echo wp_kses_post($ei_client_html); ?>
414 445 </div>
415 446 </div>
416 447 </div>
448 + <?php endif; ?>
417 449
418 450 <?php if ($quote->getDescription()): ?>
419 451 <div class="quote-description">
420 452 <div class="description-content"><?php echo wp_kses_post($quote->getDescription()); ?></div>
@@ -420,8 +452,18 @@
420 452 <div class="description-content"><?php echo wp_kses_post($quote->getDescription()); ?></div>
421 453 </div>
422 454 <?php endif; ?>
423 455
456 + <?php
457 + // The adjustment column appears only when at least one line uses it.
458 + $ei_show_adjust = \EasyInvoice\Controllers\SettingsController::shouldShowQuoteAdjustField();
459 + if ($ei_show_adjust) {
460 + $ei_show_adjust = false;
461 + foreach ($quote->getItems() as $ei_item) {
462 + if ((float) $ei_item->getAdjustPercentage() != 0.0) { $ei_show_adjust = true; break; }
463 + }
464 + }
465 + ?>
424 466 <table class="quote-items">
425 467 <thead>
426 468 <tr>
427 469 <th><?php echo esc_html($text_settings['service']); ?></th>
@@ -426,15 +468,18 @@
426 468 <tr>
427 469 <th><?php echo esc_html($text_settings['service']); ?></th>
428 470 <th><?php echo esc_html($text_settings['qty']); ?></th>
429 471 <th><?php echo esc_html($text_settings['rate_price']); ?></th>
430 - <?php if (\EasyInvoice\Controllers\SettingsController::shouldShowQuoteAdjustField()): ?>
472 + <?php if ($ei_show_adjust): ?>
431 473 <th><?php echo esc_html($text_settings['adjust']); ?> (%)</th>
432 474 <?php endif; ?>
433 - <th><?php echo esc_html($text_settings['total']); ?></th>
475 + <th><?php echo esc_html($text_settings['line_total'] ?? $text_settings['total']); ?></th>
434 476 </tr>
435 477 </thead>
436 478 <tbody>
479 + <?php if (!$quote->getItems()) : ?>
480 + <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>
481 + <?php endif; ?>
437 482 <?php foreach ($quote->getItems() as $item): ?>
438 483 <tr>
439 484 <td class="item-name">
440 485 <div class="item-title"><?php echo esc_html($item->getName()); ?></div>
@@ -443,9 +488,9 @@
443 488 <?php endif; ?>
444 489 </td>
445 490 <td class="item-quantity"><?php echo esc_html($item->getQuantity() ?: '0'); ?></td>
446 491 <td class="item-price"><?php echo esc_html((isset($formatter) && $formatter) ? $formatter->format($item->getPrice()) : (new \EasyInvoice\Helpers\QuoteFormatter($quote))->format($item->getPrice())); ?></td>
447 - <?php if (\EasyInvoice\Controllers\SettingsController::shouldShowQuoteAdjustField()): ?>
492 + <?php if ($ei_show_adjust): ?>
448 493 <td class="item-adjust"><?php
449 494 $adjust_percentage = $item->getAdjustPercentage();
450 495 if ($adjust_percentage != 0) {
451 496 echo esc_html($adjust_percentage > 0 ? '+' : '') . esc_html($adjust_percentage) . '%';
@@ -465,14 +510,15 @@
465 510 // Ensure we have a formatter
466 511 if (!isset($formatter) || !$formatter) {
467 512 $formatter = new \EasyInvoice\Helpers\QuoteFormatter($quote);
468 513 }
469 - echo \EasyInvoice\Helpers\TemplateTextHelper::generateTotalsSection($quote, $text_settings, $formatter, 'quote');
514 + echo wp_kses_post(\EasyInvoice\Helpers\TemplateTextHelper::generateTotalsSection($quote, $text_settings, $formatter, 'quote'));
470 515 ?>
516 + </div>
471 517
472 518 <?php if ($quote->getNotes()): ?>
473 519 <div class="quote-notes">
474 - <h3><?php _e('Notes:', 'easy-invoice'); ?></h3>
520 + <h3><?php esc_html_e('Notes', 'easy-invoice'); ?></h3>
475 521 <div class="notes-content">
476 522 <?php echo wp_kses_post($quote->getNotes() ?: ''); ?>
477 523 </div>
478 524 </div>
@@ -482,9 +528,9 @@
482 528 $terms_conditions = $quote->getTerms() ?: \EasyInvoice\Controllers\SettingsController::getQuoteTermsConditions();
483 529 if ($terms_conditions):
484 530 ?>
485 531 <div class="quote-terms">
486 - <h3><?php _e('Terms & Conditions:', 'easy-invoice'); ?></h3>
532 + <h3><?php esc_html_e('Terms & Conditions', 'easy-invoice'); ?></h3>
487 533 <div class="terms-content">
488 534 <?php echo wp_kses_post($terms_conditions); ?>
489 535 </div>
490 536 </div>
@@ -489,14 +535,23 @@
489 535 </div>
490 536 </div>
491 537 <?php endif; ?>
492 538
539 + <?php
540 + /**
541 + * Fires inside the document card, after notes and terms and before the
542 + * footer text: attachments, the signature block, e-invoicing notes. Being
543 + * inside the card, it is part of what "Download as PDF" captures.
544 + *
545 + * @param object $document The quote model.
546 + * @param string $type 'quote'.
547 + */
548 + do_action('easy_invoice_document_body_after', $quote, 'quote');
549 +
550 + $ei_footer_text = \EasyInvoice\Helpers\TemplateTextHelper::footerText($quote, 'quote');
551 + if ('' !== trim(wp_strip_all_tags((string) $ei_footer_text))) :
552 + ?>
493 553 <div class="quote-footer">
494 - <?php
495 - $footer_text = $quote->getFooterText();
496 - if (!$footer_text) {
497 - $footer_text = \EasyInvoice\Controllers\SettingsController::getQuoteFooterText();
498 - }
499 - ?>
500 - <p><?php echo wp_kses_post($footer_text); ?></p>
554 + <p><?php echo wp_kses_post($ei_footer_text); ?></p>
501 555 </div>
502 -</div>
556 + <?php endif; ?>
557 +</div>