PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Services / Renderer / Receipt / ReceiptRenderer.php

ReceiptRenderer.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.5, at app/Services/Renderer/Receipt/ReceiptRenderer.php

1,144 lines 57.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Services\Renderer\Receipt;
4
5 use FluentCart\App\Helpers\Helper;
6 use FluentCart\Framework\Support\Arr;
7
8 use FluentCart\Api\StoreSettings;
9 use FluentCart\App\Helpers\AddressHelper;
10 use FluentCart\App\Modules\Tax\TaxModule;
11 use FluentCart\App\Services\DateTime\DateTime;
12 use FluentCart\App\Services\DateTime\DateFormatter;
13
14 class ReceiptRenderer
15 {
16 protected $config = null;
17
18 protected $is_first_time = false;
19
20 protected $order_operation = null;
21
22 protected $settings = null;
23
24 protected $vat_tax_id = null;
25
26 protected $orderTz;
27
28 private $fctTaxSummaryCache = [];
29
30 public function __construct($config = [])
31 {
32 $this->config = $config;
33
34 $this->is_first_time = Arr::get($this->config, 'is_first_time', false);
35 $this->order_operation = Arr::get($this->config, 'order_operation', false);
36
37 $this->settings = new StoreSettings();
38
39 $this->orderTz = Arr::get($this->config, 'user_tz', 'UTC');
40 }
41
42 private function getMemoizedTaxSummary($order)
43 {
44 if (!$order) {
45 return TaxSummaryHelper::computeTaxSummary($order);
46 }
47 $id = (int) $order->id;
48 if (!isset($this->fctTaxSummaryCache[$id])) {
49 $this->fctTaxSummaryCache[$id] = TaxSummaryHelper::computeTaxSummary($order);
50 }
51 return $this->fctTaxSummaryCache[$id];
52 }
53
54 public function wrapperStart()
55 {
56 ?>
57 <div
58 class="fct-receipt-page"
59 style="background-color: #fff;max-width: 620px;margin-left: auto;margin-right: auto;border: 1px solid #e7eaee;padding: 10px;border-radius: 8px;">
60 <div
61 class="fct-receipt-page-inner"
62 style=" border-radius: 5px;" id="receipt">
63 <div class="fct-email-template-content email-template-content"
64 style="font-family: Arial, Helvetica, sans-serif; margin: 0 auto; padding: 0px; width: 100%;">
65 <div class="fct-email-template-content-inner" style="font-size: 13px;line-height: 1.4;color: #333;padding: 20px;">
66
67 <?php
68 }
69
70 public function wrapperEnd()
71 {
72 ?>
73 </div>
74 </div>
75 </div>
76 </div>
77 <?php
78 }
79
80 public function render($hideWrapper = false)
81 {
82
83 $order = Arr::get($this->config, 'order', null);
84 if (!$order) {
85 return;
86 }
87
88 $this->vat_tax_id = $order->getCustomerTaxNumber();
89
90 $profilePage = $this->settings->getCustomerProfilePage();
91 $orderTaxRates = $order->getPrimaryOrderTaxRate();
92
93 ?>
94
95 <style>
96 html {
97 background-color: rgb(248, 249, 250);
98 font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
99 }
100
101 body {
102 background-color: rgb(248, 249, 250);
103 padding-top: 40px;
104 padding-bottom: 40px;
105 font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
106 }
107
108 p {
109 font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
110 font-size: 14px;
111 margin: 0px;
112 margin-bottom: 8px;
113 line-height: 24px;
114 }
115
116 .email_footer p {
117 font-size: 12px;
118 color: rgb(127, 140, 141);
119 margin: 0px;
120 line-height: 24px;
121 margin-bottom: 8px;
122 }
123
124 hr {
125 border-color: rgb(229, 231, 235);
126 margin-bottom: 20px;
127 width: 100%;
128 border: none;
129 border-top: 1px solid #eaeaea;
130 }
131
132 .space_bottom_30 {
133 display: block;
134 width: 100%;
135 margin-bottom: 30px;
136 }
137
138 .fct-transaction-table tr:last-child td {
139 border-bottom: none !important;
140 padding-bottom: 0 !important;
141 }
142 </style>
143
144 <?php if (!$hideWrapper) {
145 $this->wrapperStart();
146 } ?>
147 <?php $this->renderHeader(); ?>
148
149 <?php $this->renderAddresses(); ?>
150
151 <?php $this->renderOrderItems(); ?>
152
153 <!-- tax note -->
154 <?php $this->renderTaxNote(); ?>
155
156 <?php $this->renderPaymentHistory(); ?>
157 <?php if (!$hideWrapper) {
158 $this->wrapperEnd();
159 } ?>
160
161
162 <?php if ($this->is_first_time) {
163 do_action('fluent_cart/order/receipt_viewed', [
164 'order' => $order,
165 'order_operation' => $this->order_operation
166 ]);
167 } ?>
168 <?php
169 }
170
171 public function renderHeader()
172 {
173 $order = Arr::get($this->config, 'order', null);
174 ?>
175 <table
176 class="fct-receipt-header"
177 role="presentation"
178 style="width: 100%;border-collapse: collapse;margin-bottom: 10px;border: none;">
179 <tbody style="width:100%">
180 <tr style="width:100%">
181 <td style="width:60%;border: none;">
182 <?php $this->renderHeaderLogo(); ?>
183
184 <!-- show tax content -->
185 <?php $this->renderStoreTaxInformation(); ?>
186 </td>
187 <td
188 class="fct-receipt-header-date"
189 style="vertical-align: middle; width: 15%; text-align: right; border: none;padding-right: 10px;">
190 <?php $this->renderHeaderOrderDate(); ?>
191 </td>
192 <td
193 class="fct-receipt-header-invoice-no"
194 style="width:15%;text-align:right;border:none;vertical-align:baseline;">
195 <?php $this->renderHeaderInvoiceNo(); ?>
196 </td>
197 </tr>
198 </tbody>
199 </table>
200 <?php
201 }
202
203 public function renderHeaderLogo()
204 {
205 ?>
206 <h1 style="font-size:24px;font-weight:700;color:rgb(17,24,39);margin:0px">
207 <?php
208 $imageLink = $this->settings->get('store_logo.url');
209 $storeName = $this->settings->get('store_name');
210 if (empty($imageLink)) {
211 echo esc_html($storeName);
212 } else {
213 echo "<img src=".esc_url($imageLink)." alt=".esc_attr($storeName)." style='max-height: 40px;'>";
214 }
215 ?>
216 </h1>
217 <?php
218 }
219
220 public function renderStoreTaxInformation()
221 {
222 $order = Arr::get($this->config, 'order', null);
223 $orderTaxRates = $order->getPrimaryOrderTaxRate();
224 $storeVatNumber = Arr::get($orderTaxRates->meta ?? [], 'store_vat_number', '');
225 $taxcountry = Arr::get($orderTaxRates->meta ?? [], 'tax_country', '');
226 if (!empty($storeVatNumber)): ?>
227 <span class="fct_invoice_tax_content" style="font-weight: 500; font-size: 14px;">
228 <?php echo esc_html(TaxModule::getCountryTaxTitle($taxcountry)); ?>:
229 <?php
230 if ($storeVatNumber !== '') {
231 echo esc_html($storeVatNumber);
232 }
233 ?>
234 </span>
235 <?php endif;
236 }
237
238 public function renderHeaderOrderDate()
239 {
240 $order = Arr::get($this->config, 'order', null);
241 ?>
242 <p style="white-space: nowrap; color: #94a3b8; text-align: right; margin: 0;font-size:12px;print-color-adjust: exact;">
243 <?php echo esc_html__('Order At', 'fluent-cart'); ?>
244 </p>
245 <p style="white-space: nowrap; font-weight: bold; color: #000; text-align: right; margin: 0;font-size:14px;">
246 <?php
247 // Through DateFormatter so the store's format and timezone settings
248 // reach this too; orderTz is only consulted on the Browser source.
249 $date = DateFormatter::format(
250 DateTime::anyTimeToGmt($order->created_at)->getTimestamp(),
251 false,
252 $this->orderTz
253 );
254 echo esc_html(Helper::translateNumber($date));
255 ?>
256 </p>
257 <?php
258 }
259
260 public function renderHeaderInvoiceNo()
261 {
262 $order = Arr::get($this->config, 'order', null);
263 ?>
264 <p style="white-space: nowrap; color: #94a3b8; text-align: right; margin: 0;font-size:12px;print-color-adjust: exact;">
265 <?php echo esc_html__('Invoice number #', 'fluent-cart'); ?>
266 </p>
267 <p id="fct-order-invoice-no"
268 style="white-space: nowrap; font-weight: bold; color: #000; text-align: right; margin: 0;font-size:14px;">
269 <?php echo esc_html($order->invoice_no); ?>
270 </p>
271 <?php
272 }
273
274 public function renderAddresses()
275 {
276 $order = Arr::get($this->config, 'order', null);
277 ?>
278
279 <?php if ($order->fulfillment_type === 'physical') : ?>
280 <div
281 class="fct-receipt-page-store-address"
282 style="background: #f8f9fa;padding: 15px;margin-bottom: 20px;print-color-adjust: exact;">
283 <?php $this->renderStoreAddress(); ?>
284 </div>
285 <?php endif; ?>
286 <div
287 class="fct-receipt-page-order-items-addresses"
288 style="display: grid;grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));gap: 20px;">
289 <?php if ($order->fulfillment_type === 'digital') : ?>
290 <div
291 class="fct-receipt-page-store-address"
292 style="border-radius: 5px;print-color-adjust: exact;">
293 <?php $this->renderStoreAddress(true); ?>
294 </div>
295 <?php endif; ?>
296 <?php $this->renderBillToAddress(); ?>
297 <?php if ($order->fulfillment_type === 'physical') : ?>
298 <?php $this->renderShipToAddress(); ?>
299 <?php endif; ?>
300 </div>
301 <?php
302 }
303
304 public function renderStoreAddress($title_border = false)
305 {
306 $order = Arr::get($this->config, 'order', null);
307 ?>
308 <?php if ($title_border) : ?>
309 <h5
310 class="fct-receipt-page-store-address-name"
311 style="font-weight: bold;font-size: 14px;margin: 0 0 10px 0;color: #495057;border-bottom: 1px solid #dee2e6;padding-bottom: 5px;">
312 <?php echo esc_html($this->settings->get('store_name')); ?>
313 </h5>
314 <?php else: ?>
315 <div
316 class="fct-receipt-page-store-address-name"
317 style="font-size: 18px;font-weight: bold;margin-bottom: 8px;">
318 <?php echo esc_html($this->settings->get('store_name')); ?>
319 </div>
320 <?php endif; ?>
321 <div
322 class="fct-receipt-page-store-address-address"
323 style="margin-bottom: 3px;">
324 <?php echo esc_html($this->settings->getFormattedFullAddress()); ?>
325 </div>
326 <?php
327 $orderTaxRates = $order->getPrimaryOrderTaxRate();
328 $storeVatNumber = Arr::get($orderTaxRates->meta ?? [], 'store_vat_number', '');
329 $taxCountry = Arr::get($orderTaxRates->meta ?? [], 'tax_country', '');
330 if (!empty($storeVatNumber)): ?>
331 <div
332 class="fct-receipt-page-store-address-vat"
333 style="margin-top: 5px;font-weight: 500;">
334 <?php echo esc_html(TaxModule::getCountryTaxTitle($taxCountry)) . ': ' . esc_html($storeVatNumber); ?>
335 </div>
336 <?php endif;
337 }
338
339 public function renderBillToAddress()
340 {
341 $order = Arr::get($this->config, 'order', null);
342 $orderTaxRates = $order->getPrimaryOrderTaxRate();
343 ?>
344 <div
345 class="fct-receipt-page-order-items-addresses-bill-to"
346 style="border-radius: 5px;print-color-adjust: exact;">
347 <h5
348 class="fct-receipt-page-order-items-addresses-bill-to-title"
349 style="font-weight: bold;font-size: 14px;margin: 0 0 10px 0;color: #495057;border-bottom: 1px solid #dee2e6;padding-bottom: 5px;">
350 <?php echo esc_html__('Bill To', 'fluent-cart'); ?>
351 </h5>
352 <?php if (!empty($order->billing_address)) : ?>
353
354 <div
355 class="fct-receipt-page-order-items-addresses-bill-to-address"
356 style="margin-bottom: 3px;">
357 <?php echo esc_html($order->billing_address->getAddressAsText()); ?>
358 </div>
359 <div
360 class="fct-receipt-page-order-items-addresses-bill-to-email"
361 style="margin-top: 10px;">
362 <?php echo esc_html($order->customer->email); ?>
363
364 </div>
365 <?php
366 $phoneNumber = Arr::get($order->billing_address->meta ?? [], 'other_data.phone', '');
367 if ($phoneNumber !== ''):
368 ?>
369 <div
370 class="fct-receipt-page-order-items-addresses-bill-to-phone"
371 style="margin-top: 3px;">
372 <?php echo esc_html($phoneNumber); ?>
373 </div>
374 <?php endif; ?>
375 <?php
376 $companyName = Arr::get($order->billing_address->meta ?? [], 'other_data.company_name', '');
377 if ($companyName === '') {
378 $companyName = $order->getCustomerTaxName();
379 }
380 if ($companyName !== ''):
381 ?>
382 <div class="fct-receipt-page-order-items-addresses-bill-to-company-name">
383 <?php echo esc_html($companyName); ?>
384 </div>
385 <?php endif; ?>
386 <?php
387 $legalRegId = Arr::get($order->billing_address->meta ?? [], 'other_data.legal_registration_id', '');
388 if ($legalRegId === '') {
389 $legalRegId = Arr::get($order->getBusinessInfo(), 'legal_registration_id', '');
390 }
391 if ($legalRegId !== ''):
392 ?>
393 <div class="fct-receipt-page-order-items-addresses-bill-to-legal-reg" style="margin-top: 3px;">
394 <?php echo esc_html__('Reg. ID', 'fluent-cart') . ': ' . esc_html($legalRegId); ?>
395 </div>
396 <?php endif; ?>
397 <div
398 class="fct-receipt-page-order-items-addresses-bill-to-vat-number"
399 style="margin-top: 5px;">
400 <?php
401 $vatNumber = $order->getCustomerTaxNumber();
402 if ($vatNumber !== '') {
403 $vatLabel = __('VAT/Tax ID', 'fluent-cart');
404 echo esc_html($vatLabel) . ': ' . esc_html($vatNumber);
405 }
406 ?>
407 </div>
408 <?php
409 $reverseChargeDeclaration = Arr::get($order->getBusinessInfo(), 'reverse_charge_declaration', '');
410 if ($reverseChargeDeclaration !== ''):
411 ?>
412 <div class="fct-receipt-page-order-items-addresses-bill-to-reverse-charge" style="margin-top: 5px;">
413 <strong><?php echo esc_html__('Reverse Charge Declaration', 'fluent-cart'); ?>:</strong>
414 <?php echo esc_html($reverseChargeDeclaration); ?>
415 </div>
416 <?php endif; ?>
417
418 <?php else: ?>
419 <div
420 class="fct-receipt-page-order-items-addresses-bill-to-name"
421 style="margin-top: 10px;">
422 <?php echo esc_html($order->customer->full_name); ?>
423 </div>
424 <div
425 class="fct-receipt-page-order-items-addresses-bill-to-email"
426 style="margin-top: 3px;">
427 <?php echo esc_html($order->customer->email); ?>
428 </div>
429 <?php endif; ?>
430 </div>
431 <?php
432 }
433
434 public function renderShipToAddress()
435 {
436 $order = Arr::get($this->config, 'order', null);
437 ?>
438 <div
439 class="fct-receipt-page-order-items-addresses-ship-to"
440 style="border-radius: 5px;print-color-adjust: exact;">
441 <h5
442 class="fct-receipt-page-order-items-addresses-ship-to-title"
443 style="font-weight: bold;font-size: 14px;margin: 0 0 10px 0;color: #495057;border-bottom: 1px solid #dee2e6;padding-bottom: 5px;">
444 <?php echo esc_html__('Ship To', 'fluent-cart'); ?>
445 </h5>
446 <?php if (!empty($order->shipping_address)) : ?>
447 <div
448 class="fct-receipt-page-order-items-addresses-ship-to-address"
449 style="margin-bottom: 3px;">
450 <?php echo esc_html($order->shipping_address->getAddressAsText()); ?>
451 </div>
452 <?php
453 $phone = Arr::get($order->shipping_address->meta ?? [], 'other_data.phone', '');
454 if ($phone !== ''):
455 ?>
456 <div
457 class="fct-receipt-page-order-items-addresses-ship-to-phone"
458 style="margin-top: 3px;">
459 <?php echo esc_html($phone); ?>
460 </div>
461 <?php endif; ?>
462 <?php else: ?>
463 <div
464 class="fct-receipt-page-order-items-addresses-ship-to-name"
465 style="margin-top: 10px;">
466 <?php echo esc_html($order->customer->full_name); ?>
467 </div>
468 <div
469 class="fct-receipt-page-order-items-addresses-ship-to-email"
470 style="margin-top: 3px;">
471 <?php echo esc_html($order->customer->email); ?>
472 </div>
473 <?php endif; ?>
474 </div>
475 <?php
476 }
477
478 public function renderOrderItems()
479 {
480 $order = Arr::get($this->config, 'order', null);
481 if ($order->order_items) : ?>
482 <?php $this->renderOrderItemsTable(); ?>
483
484 <?php $this->renderOrderItemsFooter(); ?>
485 <?php endif;
486 }
487
488 public function renderOrderItemsTable()
489 {
490 $order = Arr::get($this->config, 'order', null);
491 if ($order->order_items) : ?>
492 <table
493 class="fct-receipt-page-order-items-table"
494 style="margin-top: 20px;margin-bottom: 10px;width: 100%;text-align: left;border-spacing: 0;border-collapse: collapse;border: none;">
495 <thead>
496 <tr>
497 <th style="background-color: #f8f9fa;padding: 12px 8px;font-weight: bold;print-color-adjust: exact;border: none;">
498 <?php echo esc_html__('Description', 'fluent-cart'); ?>
499 </th>
500 <th style="background-color: #f8f9fa;padding: 12px 8px;font-weight: bold;width: 80px;text-align: right;print-color-adjust: exact;border: none;">
501 <?php echo esc_html__('Qty', 'fluent-cart'); ?>
502 </th>
503 <th style="background-color: #f8f9fa;padding: 12px 8px;font-weight: bold;width: 80px;text-align: right;print-color-adjust: exact;border: none;">
504 <?php echo esc_html__('Unit price', 'fluent-cart'); ?>
505 </th>
506 <th style="background-color: #f8f9fa;padding: 12px 8px;font-weight: bold;width: 80px;text-align: right;print-color-adjust: exact;border: none;">
507 <?php echo esc_html__('Amount', 'fluent-cart'); ?>
508 </th>
509 </tr>
510 </thead>
511 <tbody>
512 <?php
513 $orderItems = $order->order_items->toArray();
514 $isReversed = $order->isReverseChargeTaxOrder();
515 $rcMode = $order->getOrderRcMode();
516 $fctReceiptTaxDisplayMode = TaxSummaryHelper::getTaxDisplayMode();
517
518 foreach ($orderItems as $item) :
519 if (($item['payment_type'] ?? '') === 'fee') {
520 continue;
521 }
522 $itemRates = TaxSummaryHelper::getItemTaxRates($item);
523 $itemBorder = empty($itemRates) ? '1px solid #dee2e6' : 'none';
524 ?>
525 <tr>
526 <td style="font-size:15px;padding: 12px 8px;border: none;border-bottom: <?php echo esc_attr($itemBorder); ?>;print-color-adjust: exact;">
527 <?php echo esc_html($item['post_title']); ?>
528 <br>
529 <?php if (!empty($item['title'])) : ?>
530 <small style="font-size: 13px;color: #758195;">- <?php echo esc_html(!empty($item['variation_display_title']) ? $item['variation_display_title'] : $item['title']); ?></small>
531 <br>
532 <?php endif; ?>
533 <?php if (!empty($item['payment_info'])) : ?>
534 <small style="font-size: 13px;color: #758195;"><?php echo esc_html($item['payment_info']); ?></small>
535 <?php endif; ?>
536 <?php if ($fctReceiptTaxDisplayMode !== 'simplified' && empty($itemRates) && !empty($item['tax_amount'])) : ?>
537 <small style="font-size: 12px; color: #94a3b8; display:block; margin-top:2px;">
538 <?php
539 /* translators: %1$s: formatted tax amount */
540 echo esc_html(sprintf(__('Tax: %1$s', 'fluent-cart'), Helper::toDecimal((int) $item['tax_amount']))); ?>
541 </small>
542 <?php endif; ?>
543 </td>
544 <td style="padding: 12px 8px;border: none;border-bottom: <?php echo esc_attr($itemBorder); ?>;text-align: right; vertical-align: top;">
545 <?php echo esc_html(Helper::translateNumber($item['quantity'])); ?>
546 </td>
547 <?php $couponDiscount = (int) Arr::get($item['line_meta'] ?? [], 'coupon_discount', 0); ?>
548 <td style="padding: 12px 8px;border: none;border-bottom: <?php echo esc_attr($itemBorder); ?>;text-align: right; vertical-align: top;">
549 <?php echo esc_html(\FluentCart\Api\CurrencySettings::getFormattedPrice($item['unit_price'], null, false, true, true)); ?>
550 </td>
551 <td style="padding: 12px 8px;border: none;border-bottom: <?php echo esc_attr($itemBorder); ?>;text-align: right; vertical-align: top;">
552 <?php if ($couponDiscount > 0): ?>
553 <span style="text-decoration:line-through;opacity:0.5;font-size:11px;display:block;">
554 <?php echo esc_html(Helper::toDecimal($item['subtotal'])); ?>
555 </span>
556 <?php endif; ?>
557 <?php echo esc_html($item['formatted_total']); ?>
558 </td>
559 </tr>
560 <?php if ($fctReceiptTaxDisplayMode !== 'simplified' && !empty($itemRates)) : ?>
561 <tr>
562 <td colspan="4" style="padding:0 8px 8px 8px;border:none;border-bottom:1px solid #dee2e6;">
563 <?php echo $this->renderTaxRatePills($itemRates, $isReversed, $rcMode); ?>
564 </td>
565 </tr>
566 <?php endif; ?>
567 <?php endforeach; ?>
568 </tbody>
569 </table>
570 <?php endif;
571 }
572
573 public function renderOrderItemsFooter()
574 {
575 $order = Arr::get($this->config, 'order', null);
576 ?>
577 <div
578 class="fct-receipt-page-order-items-footer"
579 style="margin-top: 20px;">
580 <table
581 class="fct-receipt-page-order-items-footer-table"
582 style="max-width: 250px;width: 100%;margin-left: auto;border-collapse: collapse;background: #f8f9fa;print-color-adjust: exact;border: none; border-radius: 8px;">
583 <tbody>
584 <?php $this->renderSubtotal(); ?>
585 <?php $this->renderDiscount(); ?>
586 <?php $this->renderShipping(); ?>
587 <?php $this->renderFees(); ?>
588 <?php $this->renderTaxSummaryBox(); ?>
589 <?php $this->renderProrateCredit(); ?>
590 <?php $this->renderRefund(); ?>
591 <?php $this->renderTotal(); ?>
592 <?php $this->renderAmountPaid(); ?>
593 </tbody>
594 </table>
595 </div>
596 <?php
597 }
598
599 public function renderSubtotal()
600 {
601 $order = Arr::get($this->config, 'order', null);
602 if ($order->subtotal != ($order->total_amount - $order->total_refund) || $order->tax_total > 0): ?>
603 <tr>
604 <td style="text-align: right;border: none; padding-top: 20px;">
605 <?php echo esc_html__('Subtotal', 'fluent-cart'); ?>
606 </td>
607 <td style="font-weight:700; padding-right: 8px; padding-top: 20px;width: 100px;text-align: right;border: none;">
608 <?php echo esc_html(\FluentCart\App\Helpers\Helper::toDecimal($order->subtotal));
609 ?>
610 </td>
611 </tr>
612 <?php endif;
613 }
614
615 public function renderDiscount()
616 {
617 $order = Arr::get($this->config, 'order', null);
618 $prorateCredit = (int) \FluentCart\Framework\Support\Arr::get($order->config, 'prorate_credit', 0);
619 $upgradeDiscount = $order->manual_discount_total - $prorateCredit;
620 // When the prorate credit IS the whole discount, label the row directly
621 // instead of showing "Discount" with a single redundant breakdown row.
622 $onlyProrateCredit = $prorateCredit > 0 && $upgradeDiscount <= 0 && $order->coupon_discount_total <= 0;
623
624 if ($order->manual_discount_total + $order->coupon_discount_total > 0): ?>
625 <tr>
626 <td style="text-align: right;border: none;">
627 <?php echo $onlyProrateCredit ? esc_html__('Prorate Credit', 'fluent-cart') : esc_html__('Discount', 'fluent-cart'); ?>
628 </td>
629 <td style="padding-right:8px; width: 100px;text-align: right;border: none;">
630 - <?php echo esc_html(\FluentCart\App\Helpers\Helper::toDecimal($order->manual_discount_total + $order->coupon_discount_total)); ?>
631 </td>
632 </tr>
633 <?php if ($prorateCredit > 0 && $upgradeDiscount > 0): ?>
634 <tr>
635 <td style="padding-left:20px;text-align: right;border: none;font-size:12px;color:rgb(107,114,128);">
636 <?php echo esc_html__('Upgrade Discount', 'fluent-cart'); ?>
637 </td>
638 <td style="padding-right:8px;width: 100px;text-align: right;border: none;font-size:12px;color:rgb(107,114,128);">
639 <?php echo esc_html(\FluentCart\App\Helpers\Helper::toDecimal($upgradeDiscount)); ?>
640 </td>
641 </tr>
642 <?php endif; ?>
643 <?php if ($prorateCredit > 0 && !$onlyProrateCredit): ?>
644 <tr>
645 <td style="padding-left:20px;text-align: right;border: none;font-size:12px;color:rgb(107,114,128);">
646 <?php echo esc_html__('Prorate Credit', 'fluent-cart'); ?>
647 </td>
648 <td style="padding-right:8px;width: 100px;text-align: right;border: none;font-size:12px;color:rgb(107,114,128);">
649 <?php echo esc_html(\FluentCart\App\Helpers\Helper::toDecimal($prorateCredit)); ?>
650 </td>
651 </tr>
652 <?php endif; ?>
653 <?php endif;
654 }
655
656 public function renderProrateCredit()
657 {
658 // Rendered as a sub-row inside renderDiscount.
659 }
660
661 public function renderShipping()
662 {
663 $order = Arr::get($this->config, 'order', null);
664 if ($order->shipping_total <= 0) {
665 return;
666 }
667 $displayShipping = (int) $order->shipping_total;
668 if ($order->isReverseChargeTaxOrder()) {
669 $rcAdj = (int) Arr::get($this->getMemoizedTaxSummary($order), 'rcShippingAdjustment', 0);
670 if ($rcAdj > 0) {
671 $displayShipping = max(0, $displayShipping - $rcAdj);
672 }
673 }
674 $shippingMethodTitle = (string) Arr::get($order->config, 'shipping_method_title', '');
675 ?>
676 <tr>
677 <td style="padding: 8px 20px 8px 0;text-align: right;border: none;">
678 <?php echo esc_html__('Shipping', 'fluent-cart'); ?>
679 <?php if ($shippingMethodTitle): ?>
680 <span style="display:block;font-size:12px;color:rgb(107,114,128);line-height:18px;">
681 <?php echo esc_html($shippingMethodTitle); ?>
682 </span>
683 <?php endif; ?>
684 </td>
685 <td style="padding: 8px 8px 8px 0;width: 100px;text-align: right;border: none;">
686 <?php echo esc_html(\FluentCart\App\Helpers\Helper::toDecimal($displayShipping)); ?>
687 </td>
688 </tr>
689 <?php
690 }
691
692 public function renderFees()
693 {
694 $order = Arr::get($this->config, 'order', null);
695 if (!$order || $order->fee_total <= 0) {
696 return;
697 }
698 $feeItems = $order->feeItems()->get();
699 foreach ($feeItems as $feeItem): ?>
700 <tr>
701 <td style="padding: 8px 20px 8px 0;text-align: right;border: none;">
702 <?php echo esc_html($feeItem->title); ?>
703 </td>
704 <td style="padding: 8px 8px 8px 0;width: 100px;text-align: right;border: none;">
705 <?php echo esc_html(\FluentCart\App\Helpers\Helper::toDecimal($feeItem->subtotal)); ?>
706 </td>
707 </tr>
708 <?php endforeach;
709 }
710
711 public function renderRefund()
712 {
713 $order = Arr::get($this->config, 'order', null);
714 if ($order->total_refund > 0): ?>
715 <tr style="font-weight: bold;font-size: 14px;">
716 <td style="font-weight:500;padding: 8px 20px 8px 0;text-align: right;border:none;">
717 <?php echo esc_html__('Refund', 'fluent-cart'); ?>
718 </td>
719 <td style="padding: 8px 8px 8px 0;width: 100px;text-align: right;border:none;">
720 - <?php echo esc_html(\FluentCart\App\Helpers\Helper::toDecimal($order->total_refund)); ?>
721 </td>
722 </tr>
723 <?php endif;
724 }
725
726 public function renderTotal()
727 {
728 $order = Arr::get($this->config, 'order', null);
729 $displayTotal = (int) $order->total_amount - (int) $order->total_refund;
730 if ($order->isReverseChargeTaxOrder()) {
731 $rcAdj = (int) Arr::get($this->getMemoizedTaxSummary($order), 'rcTotalAdjustment', 0);
732 if ($rcAdj > 0) {
733 $displayTotal = max(0, $displayTotal - $rcAdj);
734 }
735 }
736 ?>
737 <tr style="font-weight: bold;font-size: 14px;">
738 <td style="font-weight:500;text-align: right;border:none;">
739 <?php echo esc_html__('Total', 'fluent-cart'); ?>
740 </td>
741 <td style="width: 100px;text-align: right;border:none; padding-right: 8px;">
742 <?php echo esc_html(\FluentCart\Api\CurrencySettings::getFormattedPrice($displayTotal, null, false, true, true)); ?>
743 </td>
744 </tr>
745 <?php
746 }
747
748 public function renderAmountPaid()
749 {
750 $order = Arr::get($this->config, 'order', null);
751 ?>
752 <tr style="font-weight: bold;font-size: 14px;">
753 <td style="font-weight:500;text-align: right;border:none; padding-bottom: 20px">
754 <?php echo esc_html__('Amount Paid', 'fluent-cart'); ?>
755 </td>
756 <td style="width: 100px;text-align: right;border:none;padding-bottom: 20px; padding-right: 8px;">
757 <?php echo esc_html(\FluentCart\Api\CurrencySettings::getFormattedPrice(($order->total_paid - $order->total_refund), null, false, true, true)); ?>
758 </td>
759 </tr>
760 <?php
761 }
762
763 public function renderTaxNote()
764 {
765 $order = Arr::get($this->config, 'order', null);
766 if ($order->isReverseChargeTaxOrder()): ?>
767
768 <div style="text-align: right; font-size: 14px; margin-top: 10px;">
769 <?php echo '*' . esc_html(TaxModule::getReverseChargeNoticeText()); ?>
770 </div>
771
772 <?php endif;
773 }
774
775 public function renderPaymentHistory()
776 {
777 $order = Arr::get($this->config, 'order', null);
778 $transactions = $order->transactions;
779 if (!empty($transactions)) :
780 ?>
781 <div
782 class="fct-payment-history"
783 style="margin-top: 30px;">
784 <div
785 class="fct-payment-history-heading"
786 style="font-weight: bold;font-size: 14px;color: #495057;margin: 0;padding: 0;">
787 <?php echo esc_html__('Payment history', 'fluent-cart'); ?>
788 </div>
789 <table class="fct-transaction-table"
790 style="margin-top: 10px;width: 100%;text-align: left;border-spacing: 0;border-collapse: collapse;border: none;">
791 <thead>
792 <tr>
793 <th style="background-color: #f8f9fa;padding: 12px 8px;font-weight: bold;print-color-adjust: exact;border:none;">
794 <?php echo esc_html__('Payment method', 'fluent-cart'); ?>
795 </th>
796 <th style="background-color: #f8f9fa;padding: 12px 8px;font-weight: bold; text-align: center;print-color-adjust: exact;border:none;">
797 <?php echo esc_html__('Date', 'fluent-cart'); ?>
798 </th>
799 <th style="background-color: #f8f9fa;padding: 12px 8px;font-weight: bold; text-align: right;print-color-adjust: exact;border:none;">
800 <?php echo esc_html__('Amount', 'fluent-cart'); ?>
801 </th>
802 </tr>
803 </thead>
804 <tbody>
805 <?php foreach ($transactions as $transaction) :
806 if ($transaction->transaction_type === 'refund') {
807 continue;
808 }
809 ?>
810 <tr>
811 <td style="padding: 10px;border:none;border-bottom: 1px solid #dee2e6;">
812 <?php echo esc_html($transaction->getPaymentMethodText()); ?>
813 </td>
814 <td style="padding: 10px;border:none;border-bottom: 1px solid #dee2e6;text-align: center;">
815 <?php
816 // Same route as the Order At header above, or
817 // one receipt renders two different formats.
818 $date = DateFormatter::format(
819 DateTime::anyTimeToGmt($transaction->created_at)->getTimestamp(),
820 false,
821 $this->orderTz
822 );
823 echo esc_html(Helper::translateNumber($date));
824 ?>
825 </td>
826 <td style="padding: 10px;border:none;border-bottom: 1px solid #dee2e6;text-align: right;">
827 <?php echo esc_html(\FluentCart\Api\CurrencySettings::getFormattedPrice($transaction->total, null, false, true, true)); ?>
828 </td>
829 </tr>
830 <?php endforeach; ?>
831 </tbody>
832 </table>
833 </div>
834 <?php endif;
835 }
836
837 public function renderConfirmationError($errorData)
838 {
839 $failed_reason = Arr::get($errorData, 'failed_reason', '');
840 $custom_payment_url = Arr::get($errorData, 'custom_payment_url', '');
841 ?>
842 <style>
843 .fluent_cart_confirmation_failed {
844 max-width: 700px;
845 margin: 0 auto;
846 padding: 30px;
847 border-radius: 9px;
848 box-shadow: 1px 1px 5px 0px #ccc;
849 border-left: 3px solid red;
850 }
851 </style>
852 <div class="fluent_cart_confirmation_failed">
853 <h3><?php echo esc_html__('Payment Confirmation Failed!', 'fluent-cart'); ?></h3>
854 <span><?php echo esc_html__('We are sorry, your order is placed but payment confirmation has failed.', 'fluent-cart'); ?></span>
855 <?php if ($failed_reason) : ?>
856 <p style="color:red;font-style: italic;"><?php echo esc_html__('Failure reason: ', 'fluent-cart') . esc_html($failed_reason) ?></p>
857 <?php endif; ?>
858 <span><?php echo esc_html__('Please try to complete payment again from here!', 'fluent-cart'); ?></span>
859 <a href="<?php echo esc_url($custom_payment_url ?? ''); ?>"><?php echo esc_url($custom_payment_url); ?></a>
860 </div>
861 <?php }
862
863 private function renderTaxRatePills(array $rates, bool $isReversed = false, string $rcMode = 'fixed')
864 {
865 $html = '';
866 foreach ($rates as $rate) {
867 $isInclusive = !empty($rate['inclusive']);
868 $badgeBg = $isInclusive ? '#EAF3DE' : '#FAEEDA';
869 $textColor = $isInclusive ? '#3B6D11' : '#854F0B';
870 $shouldStrike = $isReversed && (!$isInclusive || $rcMode === 'dynamic');
871 $amountStyle = 'color:' . esc_attr($textColor) . ';font-size:11px;font-weight:500;'
872 . ($shouldStrike ? 'text-decoration:line-through;opacity:0.6;' : '');
873 /* translators: %1$s: formatted tax amount (e.g. $12.00) */
874 $amountDisplay = $isInclusive
875 ? esc_html(sprintf(__('incl. %1$s', 'fluent-cart'), Helper::toDecimal($rate['tax_amount'])))
876 : esc_html(Helper::toDecimal($rate['tax_amount']));
877 $html .= '<table width="100%" cellpadding="0" cellspacing="0" style="border:none;margin-top:3px;">';
878 $html .= '<tr>';
879 $html .= '<td style="padding:0;border:none;">';
880 $html .= '<span style="background-color:' . esc_attr($badgeBg) . ';color:' . esc_attr($textColor) . ';font-size:11px;padding:2px 7px;border-radius:4px;display:inline-block;">' . esc_html($rate['label']) . ' (' . esc_html(number_format((float) $rate['rate_percent'], 0)) . '%)</span>';
881 $html .= '</td>';
882 $html .= '<td style="text-align:right;padding:0;border:none;white-space:nowrap;">';
883 $html .= '<span style="' . $amountStyle . '">' . $amountDisplay . '</span>';
884 $html .= '</td>';
885 $html .= '</tr>';
886 $html .= '</table>';
887 }
888 return $html;
889 }
890
891 public function renderTaxSummaryBox()
892 {
893 $order = Arr::get($this->config, 'order', null);
894 $summary = $this->getMemoizedTaxSummary($order);
895 if (!$summary['shouldRender']) {
896 return;
897 }
898 ?>
899 <tr>
900 <td colspan="2" style="padding: 6px 8px;">
901 <table width="100%" cellpadding="0" cellspacing="0" style="border:1px solid #e2e8f0; border-radius:6px; border-collapse:separate; background:#ffffff; -webkit-print-color-adjust:exact; print-color-adjust:exact;">
902 <tr>
903 <td style="padding:6px 8px 6px 0;">
904 <table width="100%" cellpadding="0" cellspacing="0" style="border:none;border-collapse:collapse;">
905 <?php if (($summary['displayMode'] ?? '') === 'simplified' && !empty($summary['simpleLine'])): ?>
906 <tr>
907 <td style="padding:4px 0 3px 8px; font-size:11px; font-weight:600; color:#1e293b; text-align:left;">
908 <?php echo esc_html($summary['simpleLine']['label']); ?>
909 </td>
910 <td style="padding:4px 0 3px; font-size:11px; font-weight:600; color:#1e293b; text-align:right;">
911 <?php echo esc_html($summary['simpleLine']['value']); ?>
912 </td>
913 </tr>
914 <?php endif; ?>
915 <?php if (($summary['displayMode'] ?? '') !== 'simplified'): ?>
916 <tr>
917 <td colspan="2" style="padding:0 0 3px 0; font-size:10px; font-weight:600;
918 text-transform:uppercase; letter-spacing:0.06em; color:#64748b;">
919 <?php if (!empty(Arr::get($summary, 'foldedRateLines', []))): ?>
920 <?php echo esc_html__('Tax breakdown by rate', 'fluent-cart'); ?>
921 <?php else: ?>
922 <?php echo esc_html__('TAX SUMMARY', 'fluent-cart'); ?>
923 <?php endif; ?>
924 </td>
925 </tr>
926 <?php
927 $foldedRateLines = Arr::get($summary, 'foldedRateLines', []);
928 $rcIsReverseCharge = !empty($summary['isReverseCharge']);
929 $rcReversedTotal = (int) Arr::get($summary, 'reversedTaxTotal', 0);
930 $rcReversedShipping = (int) Arr::get($summary, 'reversedShippingTax', 0);
931 $rcReversedValue = $rcReversedTotal > 0
932 ? Helper::toDecimal($rcReversedTotal)
933 : __('Charge reversed', 'fluent-cart');
934 $includedInPrices = (int) Arr::get($summary, 'includedInPrices', 0);
935 ?>
936 <?php if (!empty($foldedRateLines)): ?>
937 <tr>
938 <td colspan="2" style="padding:2px 0 0 0;">
939 <table width="100%" cellpadding="0" cellspacing="0" style="border:none;border-collapse:collapse;table-layout:fixed;">
940 <tr>
941 <td style="width:58%;padding:3px 8px 3px 8px; font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em; color:#64748b; vertical-align:top;">
942 <?php echo esc_html__('Rate', 'fluent-cart'); ?>
943 </td>
944 <td style="width:24%;padding:3px 8px 3px 0; font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em; color:#64748b; text-align:right; white-space:nowrap; vertical-align:top;">
945 <?php echo esc_html__('Taxable base', 'fluent-cart'); ?>
946 </td>
947 <td style="width:18%;padding:3px 0 3px; font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em; color:#64748b; text-align:right; white-space:nowrap; vertical-align:top;">
948 <?php echo esc_html__('Tax', 'fluent-cart'); ?>
949 </td>
950 </tr>
951 <?php foreach ($foldedRateLines as $foldedRow):
952 $foldedColor = !empty($foldedRow['inclusive']) ? '#94a3b8' : '#334155'; ?>
953 <tr>
954 <td style="width:58%;padding:3px 8px 3px 8px; font-size:11px; color:<?php echo esc_attr($foldedColor); ?>; text-align:left; white-space:normal; word-break:break-word; overflow-wrap:break-word; vertical-align:top;">
955 <?php echo esc_html($foldedRow['label']); ?>
956 </td>
957 <td style="width:24%;padding:3px 8px 3px 0; font-size:11px; color:<?php echo esc_attr($foldedColor); ?>; text-align:right; white-space:nowrap; vertical-align:top;">
958 <?php echo esc_html(Helper::toDecimal((int) $foldedRow['base'])); ?>
959 </td>
960 <td style="width:18%;padding:3px 0 3px; font-size:11px; color:<?php echo esc_attr($foldedColor); ?>; text-align:right; white-space:nowrap; vertical-align:top;">
961 <?php echo esc_html(Helper::toDecimal((int) $foldedRow['tax'])); ?>
962 </td>
963 </tr>
964 <?php endforeach; ?>
965 </table>
966 </td>
967 </tr>
968 <?php if ($rcIsReverseCharge): ?>
969 <tr>
970 <td style="padding:3px 0 4px 8px; font-size:11px; font-weight:600; color:#1e293b; text-align: left;">
971 <?php echo esc_html__('VAT reversed', 'fluent-cart'); ?>
972 </td>
973 <td style="padding:3px 0 4px; font-size:11px; text-align:right; font-weight:600; color:#1e293b;">
974 <?php echo esc_html($rcReversedValue); ?>
975 </td>
976 </tr>
977 <?php else: ?>
978 <tr>
979 <td style="padding:4px 0 3px 8px; font-size:11px; font-weight:600; color:#1e293b; border-top:1px solid #e2e8f0; text-align:left;">
980 <?php echo esc_html__('Total tax', 'fluent-cart'); ?>
981 </td>
982 <td style="padding:4px 0 3px; font-size:11px; font-weight:600; color:#1e293b; border-top:1px solid #e2e8f0; text-align:right;">
983 <?php echo esc_html(Helper::toDecimal((int) $summary['totalOrderTax'])); ?>
984 </td>
985 </tr>
986 <?php if ($includedInPrices > 0): ?>
987 <tr>
988 <td style="padding:3px 0 3px 8px; font-size:11px; color:#94a3b8; text-align:left;">
989 <?php echo esc_html__('of which included in prices', 'fluent-cart'); ?>
990 </td>
991 <td style="padding:3px 0 3px; font-size:11px; color:#94a3b8; text-align:right;">
992 <?php echo esc_html(Helper::toDecimal($includedInPrices)); ?>
993 </td>
994 </tr>
995 <?php endif; ?>
996 <?php if ($summary['payableTax'] > 0 && $includedInPrices > 0): ?>
997 <tr>
998 <td style="padding:3px 0 4px 8px; font-size:11px; color:#334155; text-align:left; border-top:1px solid #e2e8f0; padding-top:6px;">
999 <?php echo esc_html__('Payable now (added)', 'fluent-cart'); ?>
1000 </td>
1001 <td style="padding:3px 0 4px; font-size:11px; color:#334155; text-align:right; border-top:1px solid #e2e8f0; padding-top:6px;">
1002 <?php echo esc_html(Helper::toDecimal((int) $summary['payableTax'])); ?>
1003 </td>
1004 </tr>
1005 <?php endif; ?>
1006 <?php endif; ?>
1007 <?php elseif ($rcIsReverseCharge): ?>
1008 <?php if ($summary['showRcShippingRow'] && $rcReversedShipping > 0): ?>
1009 <tr>
1010 <td style="padding:3px 0 3px 8px; font-size:11px; color:#94a3b8;">
1011 <?php echo esc_html__('Added on shipping', 'fluent-cart'); ?>
1012 </td>
1013 <td style="padding:3px 0 3px; font-size:11px; text-align:right; color:#94a3b8;">
1014 <span style="text-decoration:line-through;opacity:0.6;"><?php echo esc_html(Helper::toDecimal($rcReversedShipping)); ?></span>
1015 </td>
1016 </tr>
1017 <?php endif; ?>
1018 <tr>
1019 <td style="padding:3px 0 4px 8px; font-size:11px; font-weight:600; color:#1e293b; text-align: left;">
1020 <?php echo esc_html__('Tax reversed', 'fluent-cart'); ?>
1021 </td>
1022 <td style="padding:3px 0 4px; font-size:11px; text-align:right; font-weight:600; color:#1e293b;">
1023 <?php echo esc_html($rcReversedValue); ?>
1024 </td>
1025 </tr>
1026 <?php else: ?>
1027 <?php
1028 $rcFeeRows = Arr::get($summary, 'feeTaxLineRows', []);
1029 $taxRateLines = Arr::get($summary, 'taxRateLines', []);
1030 $productTaxRowCount = !empty($taxRateLines)
1031 ? count($taxRateLines)
1032 : (int) ($summary['inclusiveTax'] > 0) + (int) ($summary['exclusiveTax'] > 0);
1033 $rowCount = $productTaxRowCount + count($rcFeeRows) + (int) ($summary['shippingTax'] > 0);
1034 $shippingTaxLines = Arr::get($summary, 'shippingTaxLines', []);
1035 $shouldShowBreakdown = !empty($taxRateLines)
1036 || !empty($shippingTaxLines)
1037 || $rowCount >= 2
1038 || ($rowCount === 1 && !($summary['payableTax'] > 0 || $summary['inclusiveTax'] > 0 || (int) Arr::get($summary, 'inclusiveFeeTax', 0) > 0));
1039 ?>
1040 <?php if (!empty($taxRateLines) && $shouldShowBreakdown): ?>
1041 <?php foreach ($taxRateLines as $taxLine):
1042 $taxLineColor = !empty($taxLine['inclusive']) ? '#94a3b8' : '#334155'; ?>
1043 <tr>
1044 <td style="padding:3px 0 3px 8px; font-size:11px; color:<?php echo esc_attr($taxLineColor); ?>; text-align: left;">
1045 <?php echo esc_html($taxLine['label']); ?>
1046 </td>
1047 <td style="padding:3px 0 3px; font-size:11px; text-align:right; color:<?php echo esc_attr($taxLineColor); ?>;">
1048 <?php echo esc_html(Helper::toDecimal($taxLine['order_tax'])); ?>
1049 </td>
1050 </tr>
1051 <?php endforeach; ?>
1052 <?php endif; ?>
1053 <?php if (empty($taxRateLines) && $summary['inclusiveTax'] > 0 && $shouldShowBreakdown): ?>
1054 <tr>
1055 <td style="padding:3px 0 3px 8px; font-size:11px; color:#94a3b8;">
1056 <?php echo esc_html__('Included in item prices', 'fluent-cart'); ?>
1057 </td>
1058 <td style="padding:3px 0 3px; font-size:11px; text-align:right; color:#94a3b8;">
1059 <?php echo esc_html(Helper::toDecimal($summary['inclusiveTax'])); ?>
1060 </td>
1061 </tr>
1062 <?php endif; ?>
1063 <?php if (empty($taxRateLines) && $summary['exclusiveTax'] > 0 && $shouldShowBreakdown): ?>
1064 <tr>
1065 <td style="padding:3px 0 3px 8px; font-size:11px; color:#334155; text-align: left;">
1066 <?php echo esc_html__('Added on products', 'fluent-cart'); ?>
1067 </td>
1068 <td style="padding:3px 0 3px; font-size:11px; text-align:right; color:#334155;">
1069 <?php echo esc_html(Helper::toDecimal($summary['exclusiveTax'])); ?>
1070 </td>
1071 </tr>
1072 <?php endif; ?>
1073 <?php if ($shouldShowBreakdown) : ?>
1074 <?php foreach ($rcFeeRows as $feeRow) :
1075 $feeRowColor = $feeRow['inclusive'] ? '#94a3b8' : '#334155'; ?>
1076 <tr>
1077 <td style="padding:3px 0 3px 8px; font-size:11px; color:<?php echo esc_attr($feeRowColor); ?>; text-align: left;">
1078 <?php echo esc_html($feeRow['display_label']); ?>
1079 </td>
1080 <td style="padding:3px 0 3px; font-size:11px; text-align:right; color:<?php echo esc_attr($feeRowColor); ?>;">
1081 <?php echo esc_html(Helper::toDecimal($feeRow['tax_amount'])); ?>
1082 </td>
1083 </tr>
1084 <?php endforeach; ?>
1085 <?php endif; ?>
1086 <?php if ($summary['shippingTax'] > 0 && $shouldShowBreakdown):
1087 $isShippingInclusive = (bool) Arr::get($summary, 'isShippingInclusive', false);
1088 $shippingRowColor = $isShippingInclusive ? '#94a3b8' : '#334155';
1089 if (!empty($shippingTaxLines)):
1090 foreach ($shippingTaxLines as $shLine): ?>
1091 <tr>
1092 <td style="padding:3px 0 3px 8px; font-size:11px; color:<?php echo esc_attr($shippingRowColor); ?>;">
1093 <?php echo esc_html($shLine['label']); ?>
1094 </td>
1095 <td style="padding:3px 0 3px; font-size:11px; text-align:right; color:<?php echo esc_attr($shippingRowColor); ?>;">
1096 <?php echo esc_html(Helper::toDecimal($shLine['shipping_tax'])); ?>
1097 </td>
1098 </tr>
1099 <?php endforeach;
1100 else: ?>
1101 <tr>
1102 <td style="padding:3px 0 3px 8px; font-size:11px; color:<?php echo esc_attr($shippingRowColor); ?>;">
1103 <?php echo esc_html($isShippingInclusive ? __('Included in shipping prices', 'fluent-cart') : __('Added on shipping', 'fluent-cart')); ?>
1104 </td>
1105 <td style="padding:3px 0 3px; font-size:11px; text-align:right; color:<?php echo esc_attr($shippingRowColor); ?>;">
1106 <?php echo esc_html(Helper::toDecimal($summary['shippingTax'])); ?>
1107 </td>
1108 </tr>
1109 <?php endif; ?>
1110 <?php endif; ?>
1111 <?php if ($summary['payableTax'] > 0): ?>
1112 <tr>
1113 <td style="padding:4px 0 4px 8px; font-size:11px; font-weight:600; color:#1e293b;
1114 border-top:1px solid #e2e8f0; text-align: left;">
1115 <?php echo esc_html__('Total payable tax', 'fluent-cart'); ?>
1116 </td>
1117 <td style="padding:4px 0 4px; font-size:11px; text-align:right; font-weight:600; color:#1e293b;
1118 border-top:1px solid #e2e8f0;">
1119 <?php echo esc_html(Helper::toDecimal($summary['payableTax'])); ?>
1120 </td>
1121 </tr>
1122 <?php endif; ?>
1123 <?php if ($summary['inclusiveTax'] > 0 || $summary['inclusiveFeeTax'] > 0): ?>
1124 <tr>
1125 <td style="padding:3px 0 4px 8px; font-size:11px; color:#94a3b8;">
1126 <?php echo esc_html__('Total tax in this order', 'fluent-cart'); ?>
1127 </td>
1128 <td style="padding:3px 0 4px; font-size:11px; text-align:right; color:#94a3b8;">
1129 <?php echo esc_html(Helper::toDecimal($summary['totalOrderTax'])); ?>
1130 </td>
1131 </tr>
1132 <?php endif; ?>
1133 <?php endif; ?>
1134 <?php endif; ?>
1135 </table>
1136 </td>
1137 </tr>
1138 </table>
1139 </td>
1140 </tr>
1141 <?php
1142 }
1143 }
1144