| @@ -42,8 +42,27 @@ | ||
| 42 | 42 | self::notifyAdminCancellation($bookingId, $bookingData); |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | /** |
| 46 | + * Resend just the customer payment-received email (part- or full-payment | |
| 47 | + * template, exactly as the automated flow chooses it). Public entry for the | |
| 48 | + * admin "resend email" action. | |
| 49 | + */ | |
| 50 | + public static function resendCustomerPaymentEmail(array $paymentData): void | |
| 51 | + { | |
| 52 | + self::notifyCustomerPaymentReceived($paymentData); | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Resend just the admin payment-received notification. Public entry for the | |
| 57 | + * admin "resend email" action. | |
| 58 | + */ | |
| 59 | + public static function resendAdminPaymentEmail(array $paymentData): void | |
| 60 | + { | |
| 61 | + self::notifyAdminPaymentReceived($paymentData); | |
| 62 | + } | |
| 63 | + | |
| 64 | + /** | |
| 46 | 65 | * Notify admin of new booking |
| 47 | 66 | */ |
| 48 | 67 | private static function notifyAdminNewBooking(int $bookingId, $bookingData): void |
| 49 | 68 | { |
| @@ -97,9 +116,17 @@ | ||
| 97 | 116 | } |
| 98 | 117 | |
| 99 | 118 | $vars = TransactionalEmailTemplateService::variablesFromBooking($booking); |
| 100 | 119 | $vars['payment_amount_formatted'] = yatra_format_price((float) ($paymentData['amount'] ?? 0)); |
| 101 | - $vars['payment_method'] = (string) ($paymentData['payment_method'] ?? __('Online payment', 'yatra')); | |
| 120 | + // Name the gateway the way the customer saw it at checkout (the | |
| 121 | + // operator's Gateway Title), not its internal id — a Stripe capture | |
| 122 | + // passes the slug "stripe" here. A manually recorded payment passes | |
| 123 | + // free text ("Credit Card"), which is not a gateway id and is returned | |
| 124 | + // unchanged. | |
| 125 | + $vars['payment_method'] = yatra_payment_gateway_label( | |
| 126 | + isset($paymentData['payment_method']) ? (string) $paymentData['payment_method'] : null, | |
| 127 | + __('Online payment', 'yatra') | |
| 128 | + ); | |
| 102 | 129 | $vars['transaction_id'] = (string) ($paymentData['transaction_id'] ?? ''); |
| 103 | 130 | |
| 104 | 131 | TransactionalEmailTemplateService::sendIfEnabled( |
| 105 | 132 | TransactionalEmailTemplateService::TYPE_ADMIN_PAYMENT_RECEIVED, |
| @@ -116,13 +143,18 @@ | ||
| 116 | 143 | * until its operator opts in: |
| 117 | 144 | * |
| 118 | 145 | * 1. a balance is genuinely still outstanding on the booking, |
| 119 | 146 | * 2. deposits / partial payments are switched on at all, and |
| 120 | - * 3. the operator has enabled the separate part-payment template. | |
| 147 | + * 3. the operator has enabled the separate part-payment template — | |
| 148 | + * either the free "Partial Payment Received" toggle, or (Pro Email | |
| 149 | + * Automation) the active "Partial Payment Received" DB template. On a | |
| 150 | + * Pro site the Email → Templates switch only writes the Pro row, so | |
| 151 | + * the free toggle stays at its default and must not be the sole gate. | |
| 121 | 152 | */ |
| 122 | 153 | private static function paymentTemplateTypeFor(object $booking): string |
| 123 | 154 | { |
| 124 | 155 | $full = TransactionalEmailTemplateService::TYPE_PAYMENT_CONFIRMATION; |
| 156 | + $partial = TransactionalEmailTemplateService::TYPE_PARTIAL_PAYMENT_RECEIVED; | |
| 125 | 157 | |
| 126 | 158 | // Nothing left to pay → this is the full-payment confirmation. |
| 127 | 159 | if ((float) ($booking->amount_due ?? 0) <= 0) { |
| 128 | 160 | return $full; |
| @@ -131,13 +163,12 @@ | ||
| 131 | 163 | if (!yatra_partial_payments_enabled()) { |
| 132 | 164 | return $full; |
| 133 | 165 | } |
| 134 | 166 | |
| 135 | - if (!SettingsService::isEnabled('email_template_partial_payment')) { | |
| 136 | - return $full; | |
| 137 | - } | |
| 167 | + $partialEnabled = SettingsService::isEnabled('email_template_partial_payment') | |
| 168 | + || (bool) apply_filters('yatra_pro_email_automation_owns_transactional_type', false, $partial); | |
| 138 | 169 | |
| 139 | - return TransactionalEmailTemplateService::TYPE_PARTIAL_PAYMENT_RECEIVED; | |
| 170 | + return $partialEnabled ? $partial : $full; | |
| 140 | 171 | } |
| 141 | 172 | |
| 142 | 173 | /** |
| 143 | 174 | * Notify customer of payment received |
| @@ -152,9 +183,17 @@ | ||
| 152 | 183 | } |
| 153 | 184 | |
| 154 | 185 | $vars = TransactionalEmailTemplateService::variablesFromBooking($booking); |
| 155 | 186 | $vars['payment_amount_formatted'] = yatra_format_price((float) ($paymentData['amount'] ?? 0)); |
| 156 | - $vars['payment_method'] = (string) ($paymentData['payment_method'] ?? __('Online payment', 'yatra')); | |
| 187 | + // Name the gateway the way the customer saw it at checkout (the | |
| 188 | + // operator's Gateway Title), not its internal id — a Stripe capture | |
| 189 | + // passes the slug "stripe" here. A manually recorded payment passes | |
| 190 | + // free text ("Credit Card"), which is not a gateway id and is returned | |
| 191 | + // unchanged. | |
| 192 | + $vars['payment_method'] = yatra_payment_gateway_label( | |
| 193 | + isset($paymentData['payment_method']) ? (string) $paymentData['payment_method'] : null, | |
| 194 | + __('Online payment', 'yatra') | |
| 195 | + ); | |
| 157 | 196 | $vars['transaction_id'] = (string) ($paymentData['transaction_id'] ?? ''); |
| 158 | 197 | |
| 159 | 198 | TransactionalEmailTemplateService::sendIfEnabled( |
| 160 | 199 | self::paymentTemplateTypeFor($booking), |