PluginProbe
Yatra – Travel Booking & Tour Operator Software / trunk
Yatra – Travel Booking & Tour Operator Software vtrunk
3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 All 83 releases
yatra / app / Services / TaxService.php

TaxService.php in Yatra – Travel Booking & Tour Operator Software trunk, at app/Services/TaxService.php

234 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Tax Service
4 *
5 * Handles tax calculations for bookings
6 *
7 * @package Yatra\Services
8 * @since 3.0.0
9 */
10
11 declare(strict_types=1);
12
13 namespace Yatra\Services;
14
15 class TaxService
16 {
17 /**
18 * Calculate tax for a booking
19 *
20 * @param float $amount Base amount
21 * @param string|null $country Customer country (for country-specific tax)
22 * @return array Tax details with multiple taxes
23 */
24 public static function calculateTax(float $amount, ?string $country = null): array
25 {
26 // Check if tax is enabled
27 if (!SettingsService::isEnabled('enable_tax')) {
28 return [
29 'tax_amount' => 0,
30 'tax_rate' => 0,
31 'tax_inclusive' => false,
32 'taxes' => [],
33 ];
34 }
35
36 $tax_inclusive = SettingsService::isEnabled('tax_inclusive');
37 $multiple_taxes_enabled = SettingsService::isEnabled('multiple_taxes_enabled');
38
39 if ($multiple_taxes_enabled) {
40 // Calculate multiple taxes
41 return self::calculateMultipleTaxes($amount, $country, $tax_inclusive);
42 } else {
43 // Calculate single tax (backward compatibility)
44 $tax_rate = self::getTaxRate($country);
45 $tax_name = SettingsService::getString('tax_name', __('Tax', 'yatra'));
46
47 // Calculate tax amount
48 if ($tax_inclusive) {
49 // Tax is included in the price
50 $tax_amount = $amount - ($amount / (1 + ($tax_rate / 100)));
51 } else {
52 // Tax is added to the price
53 $tax_amount = $amount * ($tax_rate / 100);
54 }
55
56 return [
57 'tax_amount' => round($tax_amount, 2),
58 'tax_rate' => $tax_rate,
59 'tax_inclusive' => $tax_inclusive,
60 'tax_name' => $tax_name,
61 'taxes' => [
62 [
63 'name' => $tax_name,
64 'rate' => $tax_rate,
65 'amount' => round($tax_amount, 2),
66 ]
67 ],
68 ];
69 }
70 }
71
72 /**
73 * Calculate multiple taxes
74 */
75 private static function calculateMultipleTaxes(float $amount, ?string $country, bool $tax_inclusive): array
76 {
77 $taxes = self::getMultipleTaxes($country);
78 $total_tax_amount = 0;
79 $calculated_taxes = [];
80
81 foreach ($taxes as $tax) {
82 $tax_rate = $tax['rate'];
83 $tax_name = $tax['name'];
84
85 if ($tax_inclusive) {
86 // For tax-inclusive, calculate based on remaining amount
87 $base_amount = $amount;
88 foreach ($calculated_taxes as $calculated_tax) {
89 $base_amount -= $calculated_tax['amount'];
90 }
91 $tax_amount = $base_amount * ($tax_rate / 100);
92 } else {
93 // Tax is added to the price
94 $tax_amount = $amount * ($tax_rate / 100);
95 }
96
97 $tax_amount = round($tax_amount, 2);
98 $total_tax_amount += $tax_amount;
99
100 $calculated_taxes[] = [
101 'name' => $tax_name,
102 'rate' => $tax_rate,
103 'amount' => $tax_amount,
104 ];
105 }
106
107 return [
108 'tax_amount' => round($total_tax_amount, 2),
109 'tax_rate' => array_sum(array_column($taxes, 'rate')),
110 'tax_inclusive' => $tax_inclusive,
111 'taxes' => $calculated_taxes,
112 ];
113 }
114
115 /**
116 * Get multiple taxes configuration
117 */
118 private static function getMultipleTaxes(?string $country = null): array
119 {
120 $default_taxes = SettingsService::get('multiple_taxes', []);
121
122 // Check if country-specific taxes exist
123 $country_taxes = SettingsService::get('multiple_taxes_by_country', []);
124 if ($country && isset($country_taxes[$country])) {
125 return $country_taxes[$country];
126 }
127
128 return $default_taxes;
129 }
130
131 /**
132 * Get tax rate for a country
133 *
134 * @param string|null $country Country code
135 * @return float Tax rate percentage
136 */
137 public static function getTaxRate(?string $country = null): float
138 {
139 // Check if country-specific tax is enabled
140 if (SettingsService::isEnabled('tax_by_country') && !empty($country)) {
141 $tax_rates = SettingsService::get('tax_rates', []);
142
143 if (isset($tax_rates[$country])) {
144 return (float) $tax_rates[$country];
145 }
146 }
147
148 // Return default tax rate
149 return SettingsService::getFloat('tax_rate', 0);
150 }
151
152 /**
153 * Get tax label
154 *
155 * @return string Tax label (e.g., "VAT", "Tax", "GST")
156 */
157 public static function getTaxLabel(): string
158 {
159 return SettingsService::getString('tax_label', __('Tax', 'yatra'));
160 }
161
162 /**
163 * Get VAT number
164 *
165 * @return string VAT number
166 */
167 public static function getVATNumber(): string
168 {
169 return SettingsService::getString('vat_number', '');
170 }
171
172 /**
173 * Format tax display
174 *
175 * @param array $taxDetails Tax details from calculateTax()
176 * @return string Formatted tax display
177 */
178 public static function formatTaxDisplay(array $taxDetails): string
179 {
180 if (empty($taxDetails['taxes'])) {
181 return '';
182 }
183
184 $multiple_taxes_enabled = SettingsService::isEnabled('multiple_taxes_enabled');
185
186 if ($multiple_taxes_enabled && count($taxDetails['taxes']) > 1) {
187 // Multiple taxes - show each tax separately
188 $display_lines = [];
189 foreach ($taxDetails['taxes'] as $tax) {
190 $display_lines[] = sprintf('%s (%s%%): %s',
191 $tax['name'],
192 number_format($tax['rate'], 2),
193 yatra_format_price($tax['amount'])
194 );
195 }
196 return implode("\n", $display_lines);
197 } else {
198 // Single tax
199 $tax = $taxDetails['taxes'][0];
200 return sprintf('%s (%s%%): %s',
201 $tax['name'],
202 number_format($tax['rate'], 2),
203 yatra_format_price($tax['amount'])
204 );
205 }
206 }
207
208 /**
209 * Get tax breakdown for display
210 *
211 * @param array $taxDetails Tax details
212 * @return array Formatted tax breakdown
213 */
214 public static function getTaxBreakdown(array $taxDetails): array
215 {
216 $breakdown = [];
217
218 foreach ($taxDetails['taxes'] as $tax) {
219 $breakdown[] = [
220 'name' => $tax['name'],
221 'rate' => $tax['rate'],
222 'amount' => $tax['amount'],
223 'formatted' => sprintf('%s (%s%%): %s',
224 $tax['name'],
225 number_format($tax['rate'], 2),
226 yatra_format_price($tax['amount'])
227 ),
228 ];
229 }
230
231 return $breakdown;
232 }
233 }
234