| @@ -299,22 +299,37 @@ | ||
| 299 | 299 | $is_selected = $is_required || $is_included || in_array($svc_id, $selected_service_ids, true); |
| 300 | 300 | |
| 301 | 301 | $base_price = (float) ($svc['price'] ?? 0); |
| 302 | 302 | $price_per = $svc['price_per'] ?? 'person'; |
| 303 | - switch ($price_per) { | |
| 304 | - case 'person': | |
| 305 | - $calculated_price = $base_price * max(1, $travelers_count); | |
| 306 | - break; | |
| 307 | - case 'day': | |
| 308 | - $calculated_price = $base_price * max(1, $duration_days_for_services); | |
| 309 | - break; | |
| 310 | - case 'booking': | |
| 311 | - default: | |
| 312 | - $calculated_price = $base_price; | |
| 313 | - break; | |
| 303 | + // This MUST stay identical to the Pro charge path | |
| 304 | + // (AdditionalServicesBookingHooks::calculateServicePrice) so the | |
| 305 | + // displayed line-item equals the amount folded into the subtotal. | |
| 306 | + if (($svc['price_type'] ?? 'fixed') === 'percentage') { | |
| 307 | + // Percentage = % of the WHOLE trip base price. `$base_amount` | |
| 308 | + // already accounts for travelers/categories, so Price Per is NOT | |
| 309 | + // applied (it would double-count). Matches the "Percentage of | |
| 310 | + // Trip Price" label and the free booking-services fallback. | |
| 311 | + $unit_price = round(($base_price / 100) * $base_amount, 2); | |
| 312 | + $calculated_price = $unit_price; | |
| 313 | + } else { | |
| 314 | + // Fixed: Price Per multiplies the entered flat amount. | |
| 315 | + $unit_price = $base_price; | |
| 316 | + switch ($price_per) { | |
| 317 | + case 'person': | |
| 318 | + $calculated_price = round($unit_price * max(1, $travelers_count), 2); | |
| 319 | + break; | |
| 320 | + case 'day': | |
| 321 | + $calculated_price = round($unit_price * max(1, $duration_days_for_services), 2); | |
| 322 | + break; | |
| 323 | + case 'booking': | |
| 324 | + default: | |
| 325 | + $calculated_price = round($unit_price, 2); | |
| 326 | + break; | |
| 327 | + } | |
| 314 | 328 | } |
| 315 | 329 | |
| 316 | 330 | $svc['selected'] = $is_selected; |
| 331 | + $svc['unit_price'] = $unit_price; | |
| 317 | 332 | $svc['calculated_price'] = $calculated_price; |
| 318 | 333 | $additional_services_resolved[] = $svc; |
| 319 | 334 | |
| 320 | 335 | // Only paid (non-included) selected services contribute to the |
| @@ -365,8 +380,11 @@ | ||
| 365 | 380 | // ── Payment amounts (FlexiblePayments Pro module) ─────────────── |
| 366 | 381 | $payment_amounts = $this->calculatePaymentAmounts($final_total, $payment_method, [ |
| 367 | 382 | 'trip_id' => $trip_id, |
| 368 | 383 | 'travelers_count' => $travelers_count, |
| 384 | + // Tour start → Pro can force full payment when the tour is within | |
| 385 | + // the balance-due window (tour-anchored scheduled payments). | |
| 386 | + 'travel_date' => $travel_date, | |
| 369 | 387 | ]); |
| 370 | 388 | |
| 371 | 389 | // ── Currency ──────────────────────────────────────────────────── |
| 372 | 390 | $currency = SettingsService::getCurrency(); |