PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 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 All 84 releases
yatra / app / Services / ItineraryCostService.php

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

206 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Services;
6
7 use Yatra\Database\Tables\BookingsTable;
8 use Yatra\Repositories\ItineraryRepository;
9
10 /**
11 * Itinerary Cost Service
12 *
13 * Handles calculation and retrieval of itinerary costs for booking
14 * This is a free feature that calculates costs from itinerary activities
15 *
16 * @package Yatra\Services
17 * @since 3.0.0
18 */
19 class ItineraryCostService
20 {
21 private ItineraryRepository $itineraryRepository;
22 private static ?self $instance = null;
23
24 public function __construct()
25 {
26 $this->itineraryRepository = new ItineraryRepository();
27 }
28
29 /**
30 * Initialize the service (singleton pattern)
31 */
32 public static function init(): void
33 {
34 if (self::$instance === null) {
35 self::$instance = new self();
36
37 // Register the filter hooks only once
38 add_filter('yatra_booking_itinerary_costs', [self::$instance, 'getItineraryCosts'], 10, 5);
39 add_filter('yatra_booking_details', [self::$instance, 'addItineraryCostsToBookingDetails'], 10, 2);
40 add_filter('yatra_booking_get_services', [self::$instance, 'getItineraryCostsAsServices'], 10, 2);
41 }
42 }
43
44 /**
45 * Get itinerary costs for a trip booking
46 *
47 * @param array $costs Empty array (filter default)
48 * @param int $tripId Trip ID
49 * @param int $totalTravelers Total number of travelers
50 * @param array $travelerCounts Traveler counts by category
51 * @param string $travelDate Travel date
52 * @return array Array of itinerary costs with pricing
53 */
54 public function getItineraryCosts(array $costs, int $tripId, int $totalTravelers, array $travelerCounts, string $travelDate): array
55 {
56 try {
57 $itineraryEntries = $this->itineraryRepository->getByTripId($tripId);
58 $itineraryCosts = [];
59
60 foreach ($itineraryEntries as $entry) {
61 // Only include entries that have a cost
62 if (empty($entry->cost) || $entry->cost <= 0) {
63 continue;
64 }
65
66 // Skip day entries (item_type_id = 0) - only include actual activities
67 if (empty($entry->item_type_id) || $entry->item_type_id == 0) {
68 continue;
69 }
70
71 $costPerPerson = !empty($entry->cost_per_person);
72 $basePrice = (float) $entry->cost;
73
74 // Calculate total cost based on pricing type
75 if ($costPerPerson) {
76 $totalCost = $basePrice * $totalTravelers;
77 $pricePer = 'person';
78 } else {
79 $totalCost = $basePrice;
80 $pricePer = 'group';
81 }
82
83 $itineraryCosts[] = [
84 'id' => $entry->id,
85 'name' => $entry->title ?: $entry->item_type ?: $entry->item_name ?: 'Itinerary Activity',
86 'description' => $entry->description ?? '',
87 'price' => $basePrice,
88 'price_per' => $pricePer,
89 'total_cost' => $totalCost,
90 'cost_per_person' => $costPerPerson,
91 'item_type' => $entry->item_type,
92 'day_number' => $entry->day_number,
93 ];
94 }
95
96 //
97
98 return $itineraryCosts;
99
100 } catch (\Exception $e) {
101 return [];
102 }
103 }
104
105 /**
106 * Add itinerary costs to booking details for admin display
107 *
108 * @param array $bookingDetails Booking details array
109 * @param int $bookingId Booking ID
110 * @return array Updated booking details
111 */
112 public function addItineraryCostsToBookingDetails(array $bookingDetails, int $bookingId): array
113 {
114 try {
115 $tripId = (int) ($bookingDetails['trip_id'] ?? 0);
116 $travelersCount = (int) ($bookingDetails['travelers_count'] ?? 1);
117
118 if ($tripId <= 0) {
119 return $bookingDetails;
120 }
121
122 // Get itinerary costs for this booking
123 $itineraryCosts = $this->getItineraryCosts([], $tripId, $travelersCount, [], $bookingDetails['travel_date'] ?? '');
124
125 // Calculate total
126 $itineraryCostsTotal = array_sum(array_column($itineraryCosts, 'total_cost'));
127
128 // Add to booking details
129 $bookingDetails['itinerary_costs'] = $itineraryCosts;
130 $bookingDetails['itinerary_costs_total'] = $itineraryCostsTotal;
131
132 //
133
134 } catch (\Exception $e) {
135 }
136
137 return $bookingDetails;
138 }
139
140 /**
141 * Get itinerary costs formatted as services for admin display
142 *
143 * @param array $services Existing services array
144 * @param int $bookingId Booking ID
145 * @return array Updated services array with itinerary costs
146 */
147 public function getItineraryCostsAsServices(array $services, int $bookingId): array
148 {
149 try {
150 // Get booking details directly from database to avoid potential loops
151 global $wpdb;
152 $table_name = BookingsTable::getTableName();
153
154 $booking = $wpdb->get_row($wpdb->prepare(
155 "SELECT trip_id, travelers_count, travel_date, itinerary_costs FROM {$table_name} WHERE id = %d",
156 $bookingId
157 ));
158
159 if (!$booking) {
160 return $services;
161 }
162
163 $tripId = (int) $booking->trip_id;
164 $travelersCount = (int) $booking->travelers_count;
165
166 if ($tripId <= 0) {
167 return $services;
168 }
169
170 // Try to get itinerary costs from stored data first
171 $itineraryCosts = [];
172 if (!empty($booking->itinerary_costs)) {
173 $itineraryCosts = json_decode($booking->itinerary_costs, true) ?: [];
174 }
175
176 // If no stored costs, calculate them
177 if (empty($itineraryCosts)) {
178 $itineraryCosts = $this->getItineraryCosts([], $tripId, $travelersCount, [], $booking->travel_date ?? '');
179 }
180
181 // Format as services for admin display
182 foreach ($itineraryCosts as $cost) {
183 $services[] = [
184 'id' => $cost['id'],
185 'name' => $cost['name'],
186 'type' => 'itinerary_cost',
187 'price' => $cost['price'],
188 'price_per' => $cost['price_per'],
189 'total_cost' => $cost['total_cost'],
190 'quantity' => $cost['price_per'] === 'person' ? $travelersCount : 1,
191 'calculated_price' => $cost['total_cost'],
192 'description' => $cost['description'] ?? '',
193 'day_number' => $cost['day_number'] ?? null,
194 'item_type' => $cost['item_type'] ?? '',
195 ];
196 }
197
198 //
199
200 } catch (\Exception $e) {
201 }
202
203 return $services;
204 }
205 }
206