← All changes
|
app/Http/Controllers/FrontendControllers/CustomerOrderController.php
+78
-17
1.3.21
→
1.6.5
View file →
| @@ -20,16 +20,17 @@ | ||
| 20 | 20 | use FluentCart\App\Models\OrderTransaction; |
| 21 | 21 | use FluentCart\App\Models\ProductDownload; |
| 22 | 22 | use FluentCart\App\Models\ProductVariation; |
| 23 | 23 | use FluentCart\App\Models\Subscription; |
| 24 | +use FluentCart\App\Modules\Subscriptions\Services\SystemChargeService; | |
| 24 | 25 | use FluentCart\App\Services\FileSystem\FileManager; |
| 25 | 26 | use FluentCart\App\Services\Localization\LocalizationManager; |
| 26 | 27 | use FluentCart\App\Services\OrderService; |
| 27 | 28 | use FluentCart\App\Services\Payments\PaymentHelper; |
| 29 | +use FluentCart\App\Services\Renderer\Receipt\TaxSummaryHelper; | |
| 28 | 30 | use FluentCart\Framework\Database\Orm\Builder; |
| 29 | 31 | use FluentCart\Framework\Database\Orm\Relations\HasMany; |
| 30 | 32 | use FluentCart\Framework\Http\Request\Request; |
| 31 | -use FluentCart\App\Services\DateTime\DateTime; | |
| 32 | 33 | use FluentCart\Framework\Support\Arr; |
| 33 | 34 | use FluentCart\Framework\Support\Collection; |
| 34 | 35 | use FluentCart\Framework\Validator\Validator; |
| 35 | 36 | use FluentCartPro\App\Modules\Licensing\Models\License; |
| @@ -61,11 +62,11 @@ | ||
| 61 | 62 | $page = (int)$request->get('page', 1); |
| 62 | 63 | $search = $request->getSafe('search', 'sanitize_text_field'); |
| 63 | 64 | |
| 64 | 65 | $orders = Order::query() |
| 65 | - ->select(['invoice_no', 'id', 'parent_id', 'total_amount', 'fee_total', 'uuid', 'type', 'status', 'created_at']) | |
| 66 | + ->select(['invoice_no', 'id', 'parent_id', 'total_amount', 'fee_total', 'currency', 'uuid', 'type', 'status', 'created_at']) | |
| 66 | 67 | ->with(['order_items' => function ($query) { |
| 67 | - $query->select('id', 'order_id', 'post_title', 'title', 'quantity', 'payment_type', 'line_meta'); | |
| 68 | + $query->select('id', 'order_id', 'object_id', 'post_title', 'title', 'quantity', 'payment_type', 'line_meta', 'other_info'); | |
| 68 | 69 | }]) |
| 69 | 70 | ->where('customer_id', $customer->id) |
| 70 | 71 | ->where(function ($query) { |
| 71 | 72 | $query |
| @@ -80,11 +81,12 @@ | ||
| 80 | 81 | ->paginate($perPage, ['*'], 'page', $page); |
| 81 | 82 | |
| 82 | 83 | $orders->transform(function ($order) { |
| 83 | 84 | return [ |
| 84 | - 'created_at' => DateTime::gmtToTimezone($order->created_at, Arr::get($order->config, 'user_tz', wp_timezone_string()))->format('Y-m-d H:i:s'), | |
| 85 | + 'created_at' => $order->created_at->format('Y-m-d H:i:s'), | |
| 85 | 86 | 'invoice_no' => $order->invoice_no, |
| 86 | 87 | 'total_amount' => $order->total_amount, |
| 88 | + 'currency' => $order->currency, | |
| 87 | 89 | 'uuid' => $order->uuid, |
| 88 | 90 | 'type' => $order->type, |
| 89 | 91 | 'status' => $order->status, |
| 90 | 92 | 'renewals_count' => $order->renewals_count, |
| @@ -89,14 +91,15 @@ | ||
| 89 | 91 | 'status' => $order->status, |
| 90 | 92 | 'renewals_count' => $order->renewals_count, |
| 91 | 93 | 'order_items' => $order->order_items->map(function ($item) { |
| 92 | 94 | return [ |
| 93 | - 'id' => $item->id, | |
| 94 | - 'post_title' => $item->post_title, | |
| 95 | - 'title' => $item->title, | |
| 96 | - 'quantity' => $item->quantity, | |
| 97 | - 'payment_type' => $item->payment_type, | |
| 98 | - 'line_meta' => [ | |
| 95 | + 'id' => $item->id, | |
| 96 | + 'post_title' => $item->post_title, | |
| 97 | + 'title' => $item->title, | |
| 98 | + 'variation_display_title' => $item->variation_display_title, | |
| 99 | + 'quantity' => $item->quantity, | |
| 100 | + 'payment_type' => $item->payment_type, | |
| 101 | + 'line_meta' => [ | |
| 99 | 102 | 'bundle_parent_item_id' => Arr::get($item, 'line_meta.bundle_parent_item_id', null), |
| 100 | 103 | ] |
| 101 | 104 | ]; |
| 102 | 105 | }), |
| @@ -129,9 +132,9 @@ | ||
| 129 | 132 | |
| 130 | 133 | $order = Order::query() |
| 131 | 134 | ->where('uuid', $order_uuid) |
| 132 | 135 | ->where('customer_id', $customer->id) |
| 133 | - ->with(['customer', 'transactions', 'shipping_address', 'billing_address']) | |
| 136 | + ->with(['customer', 'transactions', 'shipping_address', 'billing_address', 'orderTaxRates.tax_rate']) | |
| 134 | 137 | ->with(['order_items' => function ($query) { |
| 135 | 138 | $query->with([ |
| 136 | 139 | 'variantImages', |
| 137 | 140 | 'product' => function ($productQuery) { |
| @@ -165,11 +168,18 @@ | ||
| 165 | 168 | |
| 166 | 169 | $orderItems = []; |
| 167 | 170 | $variationIds = []; |
| 168 | 171 | $productIds = []; |
| 172 | + | |
| 169 | 173 | foreach ($order->order_items as $item) { |
| 170 | 174 | if ($item->payment_type === 'signup_fee') { |
| 171 | - continue; // Skip signup fee items | |
| 175 | + $orderItems[] = [ | |
| 176 | + 'id' => $item->id, | |
| 177 | + 'payment_type' => $item->payment_type, | |
| 178 | + 'object_id' => $item->object_id, | |
| 179 | + 'line_meta' => $item->line_meta, | |
| 180 | + ]; | |
| 181 | + continue; | |
| 172 | 182 | } |
| 173 | 183 | |
| 174 | 184 | // Fee items: include with minimal data for frontend display |
| 175 | 185 | if ($item->payment_type === 'fee') { |
| @@ -196,9 +206,9 @@ | ||
| 196 | 206 | |
| 197 | 207 | if ($item->payment_type == 'subscription' && $signupFee = Arr::get($item->other_info, 'signup_fee')) { |
| 198 | 208 | $metaLines[] = [ |
| 199 | 209 | 'label' => Arr::get($item->other_info, 'signup_fee_name', __('Signup Fee', 'fluent-cart')), |
| 200 | - 'value' => Helper::toDecimal($signupFee, true, $order->currency) | |
| 210 | + 'value' => html_entity_decode(Helper::toDecimal($signupFee, true, $order->currency)) | |
| 201 | 211 | ]; |
| 202 | 212 | $extraAmount = (int)$signupFee; |
| 203 | 213 | } |
| 204 | 214 | |
| @@ -206,8 +216,9 @@ | ||
| 206 | 216 | 'variation_id' => $item->object_id, |
| 207 | 217 | 'product_id' => $item->post_id, |
| 208 | 218 | 'post_title' => $item->post_title, |
| 209 | 219 | 'title' => $item->title, |
| 220 | + 'variation_display_title' => $item->variation_display_title, | |
| 210 | 221 | 'quantity' => $item->quantity, |
| 211 | 222 | 'unit_price' => $item->unit_price, |
| 212 | 223 | 'subtotal' => $item->subtotal, |
| 213 | 224 | 'payment_type' => $item->payment_type, |
| @@ -217,9 +228,12 @@ | ||
| 217 | 228 | 'variant_image' => Arr::get($item, 'variantImages.meta_value.0.url', ''), |
| 218 | 229 | 'url' => $item->is_custom |
| 219 | 230 | ? ($item->view_url ?? '') : ($item->product->view_url ?? ''), |
| 220 | 231 | 'line_meta' => $item->line_meta, |
| 221 | - 'id' => $item->id | |
| 232 | + 'id' => $item->id, | |
| 233 | + 'coupon_discount' => (int) $item->coupon_discount, | |
| 234 | + 'discount_total' => (int) $item->discount_total, | |
| 235 | + 'line_total' => (int) $item->line_total, | |
| 222 | 236 | |
| 223 | 237 | ]; |
| 224 | 238 | $variationIds[] = $item->object_id; |
| 225 | 239 | $productIds[] = $item->post_id; |
| @@ -224,12 +238,35 @@ | ||
| 224 | 238 | $variationIds[] = $item->object_id; |
| 225 | 239 | $productIds[] = $item->post_id; |
| 226 | 240 | } |
| 227 | 241 | |
| 242 | + $upgradableVariationIds = []; | |
| 243 | + $isUpgradeEligibleOrder = in_array($order->payment_status, [ | |
| 244 | + Status::PAYMENT_PAID, | |
| 245 | + Status::PAYMENT_PARTIALLY_PAID, | |
| 246 | + Status::PAYMENT_PARTIALLY_REFUNDED | |
| 247 | + ]); | |
| 248 | + | |
| 249 | + if ($isUpgradeEligibleOrder && $variationIds) { | |
| 250 | + $upgradableVariationIds = Meta::query() | |
| 251 | + ->where('meta_key', 'variant_upgrade_path') | |
| 252 | + ->where('object_type', 'variant_upgrade') | |
| 253 | + ->whereIn('object_id', $variationIds) | |
| 254 | + ->pluck('object_id') | |
| 255 | + ->toArray(); | |
| 256 | + } | |
| 257 | + | |
| 258 | + foreach ($orderItems as &$orderItem) { | |
| 259 | + $orderItem['has_upgrade_paths'] = Arr::get($orderItem, 'payment_type') === 'onetime' | |
| 260 | + && !Arr::get($orderItem, 'line_meta.parent_item_id') | |
| 261 | + && in_array(Arr::get($orderItem, 'variation_id'), $upgradableVariationIds); | |
| 262 | + } | |
| 263 | + unset($orderItem); | |
| 264 | + | |
| 228 | 265 | $formattedOrderData = [ |
| 229 | 266 | 'fulfillment_type' => $order->fulfillment_type, |
| 230 | 267 | 'type' => $order->type, |
| 231 | - 'created_at' => DateTime::gmtToTimezone($order->created_at, Arr::get($order->config, 'user_tz', wp_timezone_string()))->format('Y-m-d H:i:s'), | |
| 268 | + 'created_at' => $order->created_at->format('Y-m-d H:i:s'), | |
| 232 | 269 | 'invoice_no' => $order->invoice_no, |
| 233 | 270 | 'currency' => $order->currency, |
| 234 | 271 | 'uuid' => $order->uuid, |
| 235 | 272 | 'order_items' => $orderItems, |
| @@ -245,13 +282,21 @@ | ||
| 245 | 282 | 'total_amount' => $order->total_amount, |
| 246 | 283 | 'total_paid' => $order->total_paid, |
| 247 | 284 | 'total_refund' => $order->total_refund, |
| 248 | 285 | 'shipping_total' => $order->shipping_total, |
| 286 | + 'shipping_method_title' => (string) Arr::get($order->config, 'shipping_method_title', ''), | |
| 249 | 287 | 'coupon_discount_total' => $order->coupon_discount_total, |
| 250 | 288 | 'manual_discount_total' => $order->manual_discount_total, |
| 289 | + 'prorate_credit' => (int) Arr::get($order->config, 'prorate_credit', 0), | |
| 251 | 290 | 'tax_total' => $order->tax_total, |
| 252 | 291 | 'tax_behavior' => $order->tax_behavior, |
| 253 | 292 | 'shipping_tax' => $order->shipping_tax, |
| 293 | + 'display_tax_lines' => $order->getDisplayTaxLines(), | |
| 294 | + 'display_shipping_tax_lines' => $order->getDisplayShippingTaxLines(), | |
| 295 | + 'is_reverse_charge_tax_order' => $order->isReverseChargeTaxOrder(), | |
| 296 | + 'reverse_charge_price_mode' => $order->getOrderRcMode(), | |
| 297 | + 'is_b2b_order' => $order->isB2BOrder(), | |
| 298 | + 'tax_summary' => TaxSummaryHelper::computeTaxSummary($order), | |
| 254 | 299 | 'payment_method' => $order->payment_method, |
| 255 | 300 | 'custom_payment_link' => $this->getCustomPaymentLink($order), |
| 256 | 301 | ]; |
| 257 | 302 | |
| @@ -293,9 +338,11 @@ | ||
| 293 | 338 | $transactions = OrderTransaction::query() |
| 294 | 339 | ->whereIn('order_id', $orderIds) |
| 295 | 340 | ->whereIn('status', [ |
| 296 | 341 | Status::TRANSACTION_SUCCEEDED, |
| 297 | - Status::TRANSACTION_REFUNDED | |
| 342 | + Status::TRANSACTION_REFUNDED, | |
| 343 | + Status::TRANSACTION_FAILED, | |
| 344 | + Status::TRANSACTION_PENDING, | |
| 298 | 345 | ]) |
| 299 | 346 | ->orderBy('id', 'DESC') |
| 300 | 347 | ->with(['order']) |
| 301 | 348 | ->get(); |
| @@ -300,9 +347,15 @@ | ||
| 300 | 347 | ->with(['order']) |
| 301 | 348 | ->get(); |
| 302 | 349 | |
| 303 | 350 | $formattedOrderData['transactions'] = $transactions->map(function ($transaction) { |
| 304 | - return OrderService::transformTransaction($transaction); | |
| 351 | + $transformedTransaction = OrderService::transformTransaction($transaction); | |
| 352 | + if ($transaction->status === Status::TRANSACTION_PENDING | |
| 353 | + && !empty($transformedTransaction['custom_checkout_url']) | |
| 354 | + ) { | |
| 355 | + $transformedTransaction['show_pay_now'] = true; | |
| 356 | + } | |
| 357 | + return $transformedTransaction; | |
| 305 | 358 | }); |
| 306 | 359 | |
| 307 | 360 | $formattedOrderData = apply_filters('fluent_cart/customer/order_data', $formattedOrderData, [ |
| 308 | 361 | 'order' => $order, |
| @@ -376,8 +429,16 @@ | ||
| 376 | 429 | { |
| 377 | 430 | if (!intval($order->total_amount - $order->total_paid)) { |
| 378 | 431 | return false; |
| 379 | 432 | } |
| 433 | + | |
| 434 | + if ($order->parent_id) { | |
| 435 | + $subscription = Subscription::query()->where('parent_order_id', $order->parent_id)->first(); | |
| 436 | + if ($subscription && $subscription->isSystem() && !SystemChargeService::isExhausted($subscription, $order)) { | |
| 437 | + return false; | |
| 438 | + } | |
| 439 | + } | |
| 440 | + | |
| 380 | 441 | return PaymentHelper::getCustomPaymentLink($order->uuid); |
| 381 | 442 | } |
| 382 | 443 | |
| 383 | 444 | public function getTransactionBillingAddress(Request $request, $transaction_uuid) |