| @@ -6,8 +6,9 @@ | ||
| 6 | 6 | use FluentCart\Api\StoreSettings; |
| 7 | 7 | use FluentCart\App\App; |
| 8 | 8 | use FluentCart\App\Helpers\AddressHelper; |
| 9 | 9 | use FluentCart\App\Helpers\Helper; |
| 10 | +use FluentCart\App\Helpers\Status; | |
| 10 | 11 | use FluentCart\App\Models\Model; |
| 11 | 12 | use FluentCart\App\Models\Order; |
| 12 | 13 | use FluentCart\App\Models\OrderItem; |
| 13 | 14 | use FluentCart\App\Models\OrderMeta; |
| @@ -13,8 +14,10 @@ | ||
| 13 | 14 | use FluentCart\App\Models\OrderMeta; |
| 14 | 15 | use FluentCart\App\Models\OrderTransaction; |
| 15 | 16 | use FluentCart\App\Models\ProductVariation; |
| 16 | 17 | use FluentCart\App\Models\Subscription; |
| 18 | +use FluentCart\App\Modules\Subscriptions\Services\SystemChargeService; | |
| 19 | +use FluentCart\App\Services\Payments\PaymentHelper; | |
| 17 | 20 | use FluentCart\Framework\Support\Arr; |
| 18 | 21 | |
| 19 | 22 | class OrderService |
| 20 | 23 | { |
| @@ -25,8 +28,14 @@ | ||
| 25 | 28 | * @return array |
| 26 | 29 | */ |
| 27 | 30 | public static function groupSanitizedData($order_data = []): array |
| 28 | 31 | { |
| 32 | + // fct_billing_tax_id is the checkout field name for the VAT number; normalise it to | |
| 33 | + // billing_vat_number so extractAddressData maps it into billing_address.vat_number | |
| 34 | + if (isset($order_data['fct_billing_tax_id'])) { | |
| 35 | + $order_data['billing_vat_number'] = $order_data['fct_billing_tax_id']; | |
| 36 | + unset($order_data['fct_billing_tax_id']); | |
| 37 | + } | |
| 29 | 38 | |
| 30 | 39 | $billingAddress = static::extractAddressData($order_data, 'billing_'); |
| 31 | 40 | $shippingAddress = static::extractAddressData($order_data, 'shipping_'); |
| 32 | 41 | $others = static::extractOtherData($order_data); |
| @@ -379,12 +388,12 @@ | ||
| 379 | 388 | if ($paymentType == 'subscription') { |
| 380 | 389 | if ((int)Arr::get($orderItem, 'other_info.trial_days', 0) > 0) { |
| 381 | 390 | return (int)Arr::get($orderItem, 'other_info.signup_fee', 0); |
| 382 | 391 | } |
| 383 | - return intval(($orderItem['unit_price'] * $orderItem['quantity'])) + (int)Arr::get($orderItem, 'other_info.signup_fee', 0); | |
| 392 | + return (int) Arr::get($orderItem, 'subtotal', intval($orderItem['unit_price'] * $orderItem['quantity'])) + (int)Arr::get($orderItem, 'other_info.signup_fee', 0); | |
| 384 | 393 | } |
| 385 | 394 | |
| 386 | - return intval(($orderItem['unit_price'] * $orderItem['quantity'])); | |
| 395 | + return (int) Arr::get($orderItem, 'subtotal', intval($orderItem['unit_price'] * $orderItem['quantity'])); | |
| 387 | 396 | } |
| 388 | 397 | |
| 389 | 398 | /** |
| 390 | 399 | * Get the total amount of items. |
| @@ -612,12 +621,33 @@ | ||
| 612 | 621 | 'reactivate_url' => $subscription->getReactivateUrl(), |
| 613 | 622 | 'can_upgrade' => $subscription->canUpgrade(), |
| 614 | 623 | 'can_switch_payment_method' => $subscription->canSwitchPaymentMethod(), |
| 615 | 624 | 'can_update_payment_method' => $subscription->canUpdatePaymentMethod(), |
| 616 | - 'item_name' => $subscription->item_name | |
| 625 | + 'collection_method' => $subscription->collection_method, | |
| 626 | + 'is_auto_charged' => $subscription->isSystem(), | |
| 627 | + 'item_name' => $subscription->display_item_name | |
| 617 | 628 | ]; |
| 618 | 629 | } |
| 619 | 630 | |
| 631 | + /** | |
| 632 | + * A system renewal order still inside its auto-charge retry window has no | |
| 633 | + * Pay Now — the charge is coming automatically. Other renewals unaffected. | |
| 634 | + */ | |
| 635 | + protected static function renewalPayNowAllowed(Order $order): bool | |
| 636 | + { | |
| 637 | + if (!$order->parent_id) { | |
| 638 | + return true; | |
| 639 | + } | |
| 640 | + | |
| 641 | + $subscription = Subscription::query()->where('parent_order_id', $order->parent_id)->first(); | |
| 642 | + | |
| 643 | + if (!$subscription || !$subscription->isSystem()) { | |
| 644 | + return true; | |
| 645 | + } | |
| 646 | + | |
| 647 | + return SystemChargeService::isExhausted($subscription, $order); | |
| 648 | + } | |
| 649 | + | |
| 620 | 650 | public static function transformTransaction(OrderTransaction $transaction) |
| 621 | 651 | { |
| 622 | 652 | $data = [ |
| 623 | 653 | 'uuid' => $transaction->uuid, |
| @@ -638,13 +668,27 @@ | ||
| 638 | 668 | if ($transaction->order && self::canGenerateReceiptPdf()) { |
| 639 | 669 | $data['receipt_view_url'] = $transaction->order->getReceiptViewUrl(); |
| 640 | 670 | } |
| 641 | 671 | |
| 672 | + if ($transaction->order | |
| 673 | + && $transaction->order->type === Status::ORDER_TYPE_RENEWAL | |
| 674 | + && $transaction->status === Status::TRANSACTION_PENDING | |
| 675 | + && self::renewalPayNowAllowed($transaction->order) | |
| 676 | + ) { | |
| 677 | + $data['custom_checkout_url'] = add_query_arg([ | |
| 678 | + 'fluent-cart' => 'custom_checkout', | |
| 679 | + 'order_hash' => $transaction->order->uuid, | |
| 680 | + ], home_url('/')); | |
| 681 | + } | |
| 682 | + | |
| 642 | 683 | return $data; |
| 643 | 684 | } |
| 644 | 685 | |
| 645 | 686 | public static function canGenerateReceiptPdf(): bool |
| 646 | 687 | { |
| 647 | - return App::isProActive() && defined('FLUENT_PDF'); | |
| 688 | + return (bool) apply_filters( | |
| 689 | + 'fluent_cart/pdf/can_generate_receipt', | |
| 690 | + App::isProActive() && defined('FLUENT_PDF') | |
| 691 | + ); | |
| 648 | 692 | } |
| 649 | 693 | |
| 650 | 694 | } |