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 / quote-templates / legacy.php

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

494 lines 15.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Legacy Quote Template
4 * Clean, minimalist design with traditional business layout
5 */
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit;
9 }
10 $text_settings = \EasyInvoice\Helpers\TemplateTextHelper::getQuoteTextSettings();
11 $company_info = \EasyInvoice\Helpers\TemplateTextHelper::getCompanyInfo();
12 // Ensure a formatter is available for currency formatting
13 if (!isset($formatter) || !$formatter) {
14 $formatter = new \EasyInvoice\Helpers\QuoteFormatter($quote ?? null);
15 }
16 ?>
17
18 <style>
19 /* Legacy Template Styles - Clean Minimalist Design (Older Version Style) */
20 .template-legacy {
21 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
22 max-width: 800px;
23 margin: 0 auto;
24 padding: 40px;
25 background: #ffffff;
26 color: #000000;
27 line-height: 1.5;
28 }
29
30 /* Header Section */
31 .template-legacy .quote-header {
32 display: flex;
33 justify-content: space-between;
34 align-items: flex-start;
35 }
36
37 .template-legacy .company-info {
38 flex: 1;
39 }
40
41 .template-legacy .company-logo {
42 margin-bottom: 5px;
43 }
44
45 .template-legacy .logo-image {
46 max-height: 60px;
47 max-width: 200px;
48 object-fit: contain;
49 }
50
51 .template-legacy .company-name {
52 font-size: 20px;
53 font-weight: 700;
54 color: #2563eb;
55 margin-bottom: 8px;
56 }
57
58 .template-legacy .company-details {
59 color: #333333;
60 font-size: 14px;
61 line-height: 1.4;
62 }
63
64 .template-legacy .quote-title-section {
65 text-align: right;
66 flex: 1;
67 }
68
69 .template-legacy .quote-title {
70 font-size: 20px;
71 font-weight: 700;
72 color: #000000;
73 margin-bottom: 20px;
74 }
75
76 .template-legacy .quote-meta {
77 border: 1px solid #d1d5db;
78 background: #ffffff;
79 width: 280px;
80 margin-left: auto;
81 }
82
83 .template-legacy .meta-item {
84 display: flex;
85 justify-content: space-between;
86 align-items: center;
87 padding: 12px 16px;
88 border-bottom: 1px solid #d1d5db;
89 }
90
91 .template-legacy .meta-item:last-child {
92 border-bottom: none;
93 }
94
95 .template-legacy .meta-label {
96 font-weight: 600;
97 color: #000000;
98 font-size: 13px;
99 }
100
101 .template-legacy .meta-value {
102 color: #000000;
103 font-size: 13px;
104 font-weight: 500;
105 }
106
107 .template-legacy .total-due {
108 font-weight: 700;
109 color: #000000;
110 }
111
112 /* Address Section */
113 .template-legacy .address-section {
114 margin-bottom: 20px;
115 }
116
117 .template-legacy .address-block {
118 margin-bottom: 20x;
119 }
120
121 .template-legacy .address-block h2 {
122 font-size: 16px;
123 font-weight: 700;
124 color: #000000;
125 margin-bottom: 12px;
126 text-transform: uppercase;
127 letter-spacing: 0.5px;
128 }
129
130 .template-legacy .address-content {
131 color: #333333;
132 font-size: 14px;
133 line-height: 1.4;
134 }
135
136 .template-legacy .client-name {
137 font-weight: 600;
138 color: #2563eb;
139 margin-bottom: 6px;
140 text-decoration: underline;
141 }
142
143 /* Description Section */
144 .template-legacy .description-section {
145 margin-bottom: 20px;
146 padding: 20px;
147 background: #f8f9fa;
148 border-radius: 6px;
149 border-left: 4px solid #e5e7eb;
150 }
151
152 .template-legacy .description-content {
153 color: #333333;
154 font-size: 14px;
155 line-height: 1.5;
156 }
157
158 /* Quote Items Table */
159 .template-legacy .quote-items {
160 width: 100%;
161 border-collapse: collapse;
162 margin-bottom: 20px;
163 border: 1px solid #d1d5db;
164 }
165
166 .template-legacy .quote-items thead {
167 background: #f3f4f6;
168 }
169
170 .template-legacy .quote-items th {
171 padding: 16px 20px;
172 text-align: left;
173 font-weight: 700;
174 color: #000000;
175 font-size: 13px;
176 border: 1px solid #d1d5db;
177 text-transform: uppercase;
178 letter-spacing: 0.5px;
179 }
180
181 .template-legacy .quote-items td {
182 padding: 16px 20px;
183 border: 1px solid #d1d5db;
184 font-size: 14px;
185 vertical-align: top;
186 color: #000000;
187 }
188
189 /* PDF-specific border fixes to prevent 2px borders */
190 .template-legacy .quote-items th,
191 .template-legacy .quote-items td {
192 border-width: 1px !important;
193 border-style: solid !important;
194 border-color: #d1d5db !important;
195 }
196
197 .template-legacy .quote-meta {
198 border-width: 1px !important;
199 border-style: solid !important;
200 border-color: #d1d5db !important;
201 }
202
203 .template-legacy .meta-item {
204 border-bottom-width: 1px !important;
205 border-bottom-style: solid !important;
206 border-bottom-color: #d1d5db !important;
207 }
208
209 .template-legacy .quote-items tr:last-child td {
210 border-bottom: none;
211 }
212
213 .template-legacy .quote-items tbody tr:hover {
214 background-color: #f8f9fa;
215 }
216
217 .template-legacy .item-name .item-title {
218 font-weight: 700;
219 color: #000000;
220 margin-bottom: 6px;
221 }
222
223 .template-legacy .item-name .item-description {
224 color: #666666;
225 font-size: 13px;
226 line-height: 1.4;
227 }
228
229 .template-legacy .item-quantity,
230 .template-legacy .item-price,
231 .template-legacy .item-adjust,
232 .template-legacy .item-total {
233 text-align: right;
234 }
235
236 /* Quote Totals */
237 .template-legacy .quote-totals {
238 margin-left: auto;
239 width: 320px;
240 border: 1px solid #dddddd;
241 border-radius: 4px;
242 overflow: hidden;
243 background: #ffffff;
244 }
245
246 .template-legacy .quote-total-row {
247 display: flex;
248 justify-content: space-between;
249 align-items: center;
250 padding: 14px 20px;
251 border-bottom: 1px solid #dddddd;
252 }
253
254 .template-legacy .quote-total-row:last-child {
255 border-bottom: none;
256 }
257
258 .template-legacy .quote-total-label {
259 font-weight: 600;
260 color: #333333;
261 font-size: 14px;
262 }
263
264 .template-legacy .quote-total-value {
265 color: #000000;
266 font-size: 14px;
267 font-weight: 500;
268 }
269
270 .template-legacy .quote-totals .quote-grand-total {
271 background: #f8f9fa;
272 border-top: 1px solid #dddddd;
273 margin-top: 0;
274 padding-top: 14px;
275 }
276
277 .template-legacy .quote-grand-total .quote-total-label,
278 .template-legacy .quote-totals .quote-grand-total .quote-total-value {
279 font-weight: 700;
280 font-size: 16px;
281 color: #000000;
282 }
283
284 /* Terms Section */
285 .template-legacy .terms-section {
286 margin-top: 20px;
287 padding: 20px;
288 background: #f9fafb;
289 border-radius: 8px;
290 border-left: 4px solid #e5e7eb;
291 }
292
293 .template-legacy .terms-section h3 {
294 font-size: 16px;
295 font-weight: 600;
296 color: #374151;
297 margin-bottom: 12px;
298 text-transform: uppercase;
299 letter-spacing: 0.5px;
300 }
301
302 .template-legacy .terms-content {
303 color: #6b7280;
304 font-size: 14px;
305 line-height: 1.6;
306 }
307
308 /* Footer */
309 .template-legacy .quote-footer {
310 margin-top: 20px;
311 border-top: 1px solid #e5e7eb;
312 text-align: center;
313 }
314
315 .template-legacy .quote-footer p {
316 color: #6b7280;
317 font-size: 14px;
318 margin-bottom: 16px;
319 }
320
321 .template-legacy .footer-company {
322 color: #9ca3af;
323 font-size: 13px;
324 }
325
326 /* Shared polish: numbers line up, numeric headings sit over their figures. */
327 .template-legacy .quote-items th + th { text-align: right; }
328 .template-legacy .quote-items .item-quantity,
329 .template-legacy .quote-items .item-price,
330 .template-legacy .quote-items .item-adjust,
331 .template-legacy .quote-items .item-total,
332 .template-legacy .quote-total-value { font-variant-numeric: tabular-nums; white-space: nowrap; }
333 .template-legacy .meta-value { white-space: nowrap; }
334 .template-legacy .quote-items .item-adjust { text-align: right; }
335 .template-legacy .client-contact { font-weight: 500; margin-bottom: 0.15em; }
336 .template-legacy .client-tax-number,
337 .template-legacy .company-tax-number { margin-top: 0.35em; }
338 .template-legacy .quote-items .item-description { white-space: pre-line; }
339 .template-legacy .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; }
340
341 /* Legacy: keeps its ruled grid, with softer rules and the same type size as the other designs. */
342 .template-legacy .quote-items th, .template-legacy .quote-items td { border-color: #e5e7eb !important; }
343 .template-legacy .quote-items th { background: #f9fafb; font-size: 12px; letter-spacing: 0.08em; color: #374151; }
344 .template-legacy .quote-meta, .template-legacy .meta-item { border-color: #e5e7eb !important; }
345 .template-legacy .company-name { color: #111827; }
346 .template-legacy .address-block h2 { font-size: 12px; letter-spacing: 0.12em; color: #6b7280; text-transform: uppercase; }
347 .template-legacy .terms-section, .template-legacy .description-section { background: transparent; border: 0; border-top: 1px solid #e5e7eb; border-radius: 0; padding: 16px 0 0; }
348 .template-legacy .terms-section h3 { font-size: 12px; letter-spacing: 0.12em; color: #6b7280; }
349 .template-legacy .quote-header { margin-bottom: 24px; }
350 </style>
351
352 <div class="template-legacy">
353 <div class="quote-header">
354 <div class="company-info">
355 <?php if (!empty($company_info['logo'])): ?>
356 <div class="company-logo">
357 <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)">
358 </div>
359 <?php endif; ?>
360 <div class="company-name"><?php echo esc_html($company_info['name']); ?></div>
361 <div class="company-details">
362 <?php echo wp_kses_post(\EasyInvoice\Helpers\TemplateTextHelper::generateFromSection($company_info, false, 'details-only')); ?>
363 </div>
364 </div>
365
366 <div class="quote-title-section">
367 <?php $ei_kind = \EasyInvoice\Controllers\SettingsController::getTextQuote(); $ei_title = trim((string) $quote->getTitle()); ?>
368 <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>
369 <div class="quote-meta">
370 <div class="meta-item">
371 <span class="meta-label"><?php echo esc_html($text_settings['quote_number']); ?></span>
372 <span class="meta-value"><?php echo esc_html($quote->getNumber()); ?></span>
373 </div>
374 <div class="meta-item">
375 <span class="meta-label"><?php echo esc_html($text_settings['quote_date']); ?></span>
376 <span class="meta-value"><?php echo esc_html(\EasyInvoice\Controllers\SettingsController::formatDate($quote->getIssueDate())); ?></span>
377 </div>
378 <div class="meta-item">
379 <span class="meta-label"><?php echo esc_html($text_settings['valid_until']); ?></span>
380 <span class="meta-value"><?php echo esc_html(\EasyInvoice\Controllers\SettingsController::formatDate($quote->getExpiryDate())); ?></span>
381 </div>
382 <div class="meta-item">
383 <span class="meta-label"><?php echo esc_html($text_settings['total']); ?></span>
384 <span class="meta-value total-due"><?php echo esc_html($formatter->format($quote->getTotal())); ?></span>
385 </div>
386 </div>
387 </div>
388 </div>
389
390 <?php $ei_client_html = \EasyInvoice\Helpers\TemplateTextHelper::generateClientBlock($quote); if ('' !== $ei_client_html) : ?>
391 <div class="address-section">
392 <div class="address-block">
393 <h2><?php echo esc_html($text_settings['to']); ?></h2>
394 <div class="address-content">
395 <?php echo wp_kses_post($ei_client_html); ?>
396 </div>
397 </div>
398 </div>
399 <?php endif; ?>
400
401 <?php if ($quote->getDescription()): ?>
402 <div class="description-section">
403 <div class="description-content"><?php echo wp_kses_post($quote->getDescription()); ?></div>
404 </div>
405 <?php endif; ?>
406
407 <?php
408 // The adjustment column appears only when at least one line uses it.
409 $ei_show_adjust = \EasyInvoice\Controllers\SettingsController::shouldShowQuoteAdjustField();
410 if ($ei_show_adjust) {
411 $ei_show_adjust = false;
412 foreach ($quote->getItems() as $ei_item) {
413 if ((float) $ei_item->getAdjustPercentage() != 0.0) { $ei_show_adjust = true; break; }
414 }
415 }
416 ?>
417 <table class="quote-items">
418 <thead>
419 <tr>
420 <th><?php echo esc_html($text_settings['service']); ?></th>
421 <th><?php echo esc_html($text_settings['qty']); ?></th>
422 <th><?php echo esc_html($text_settings['rate_price']); ?></th>
423 <?php if ($ei_show_adjust): ?>
424 <th><?php echo esc_html($text_settings['adjust']); ?> (%)</th>
425 <?php endif; ?>
426 <th><?php echo esc_html($text_settings['line_total'] ?? $text_settings['total']); ?></th>
427 </tr>
428 </thead>
429 <tbody>
430 <?php if (!$quote->getItems()) : ?>
431 <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>
432 <?php endif; ?>
433 <?php foreach ($quote->getItems() as $item): ?>
434 <tr>
435 <td class="item-name">
436 <div class="item-title"><?php echo esc_html($item->getName()); ?></div>
437 <?php if ($item->getDescription()): ?>
438 <div class="item-description"><?php echo esc_html($item->getDescription()); ?></div>
439 <?php endif; ?>
440 </td>
441 <td class="item-quantity"><?php echo esc_html($item->getQuantity() ?: '0'); ?></td>
442 <td class="item-price"><?php echo esc_html($formatter->format($item->getPrice())); ?></td>
443 <?php if ($ei_show_adjust): ?>
444 <td class="item-adjust"><?php
445 $adjust_percentage = $item->getAdjustPercentage();
446 if ($adjust_percentage != 0) {
447 echo esc_html($adjust_percentage > 0 ? '+' : '') . esc_html($adjust_percentage) . '%';
448 } else {
449 echo esc_html__('—', 'easy-invoice');
450 }
451 ?></td>
452 <?php endif; ?>
453 <td class="item-total"><?php echo esc_html($formatter->format($item->getAmount())); ?></td>
454 </tr>
455 <?php endforeach; ?>
456 </tbody>
457 </table>
458
459 <div class="quote-totals">
460 <?php echo wp_kses_post(\EasyInvoice\Helpers\TemplateTextHelper::generateTotalsSection($quote, $text_settings, $formatter, 'quote')); ?>
461 </div>
462
463 <?php
464 $terms_conditions = $quote->getTerms() ?: \EasyInvoice\Controllers\SettingsController::getQuoteTermsConditions();
465 if ($terms_conditions):
466 ?>
467 <div class="terms-section">
468 <h3><?php esc_html_e('Terms & Conditions', 'easy-invoice'); ?></h3>
469 <div class="terms-content">
470 <?php echo wp_kses_post($terms_conditions); ?>
471 </div>
472 </div>
473 <?php endif; ?>
474
475 <?php
476 /**
477 * Fires inside the document card, after notes and terms and before the
478 * footer text: attachments, the signature block, e-invoicing notes. Being
479 * inside the card, it is part of what "Download as PDF" captures.
480 *
481 * @param object $document The quote model.
482 * @param string $type 'quote'.
483 */
484 do_action('easy_invoice_document_body_after', $quote, 'quote');
485
486 $ei_footer_text = \EasyInvoice\Helpers\TemplateTextHelper::footerText($quote, 'quote');
487 if ('' !== trim(wp_strip_all_tags((string) $ei_footer_text))) :
488 ?>
489 <div class="quote-footer">
490 <p><?php echo wp_kses_post($ei_footer_text); ?></p>
491 </div>
492 <?php endif; ?>
493 </div>
494