PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.10.0
Fluent Support – Helpdesk & Customer Support Ticket System v1.10.0
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
fluent-support / app / Services / Integrations / FluentCart / FluentCart.php

FluentCart.php in Fluent Support – Helpdesk & Customer Support Ticket System 1.10.0, at app/Services/Integrations/FluentCart/FluentCart.php

302 lines 10.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Services\Integrations\FluentCart;
4 use FluentCart\App\Models\Order;
5 use FluentSupport\App\Services\Helper;
6 use FluentSupport\Framework\Support\Arr;
7 use FluentSupport\App\Models\Customer;
8
9 class FluentCart
10 {
11 public function boot()
12 {
13 // add_filter('fluent_support/customer_extra_widgets', array($this, 'getFluentCartPurchaseWidgets'), 120, 2);
14 // add_filter('fluent_support/customer_extra_widgets', array($this, 'getFluentCartProLicenseWidget'), 125, 2);
15 add_action('fluent_cart/order_created', [$this, 'addCustomer'], 10, 1);
16 if (!apply_filters('fluent_support/disable_fc_menu', false)) {
17 $this->renderCustomerPortalInFluentCartDashboard();
18 }
19 }
20
21 public function getFluentCartPurchaseWidgets($widgets, $customer)
22 {
23 $wpUserId = $customer->user_id;
24
25 // Get all order items for this customer, grouped by product
26 $orderItems = \FluentCart\App\Models\OrderItem::whereHas('order.customer', function ($query) use ($wpUserId) {
27 $query->where('user_id', $wpUserId);
28 })
29 ->with([
30 'order' => function ($query) {
31 $query->select(['id', 'status', 'created_at', 'total_amount', 'currency', 'invoice_no']);
32 }
33 ])
34 ->select(['id', 'order_id', 'post_id', 'post_title', 'title', 'payment_type', 'unit_price', 'subtotal', 'quantity'])
35 ->orderByDesc('id')
36 ->get();
37
38 if ($orderItems->isEmpty()) {
39 return $widgets;
40 }
41
42 // Create individual product entries for each order item (no grouping)
43 $formattedProducts = [];
44
45 foreach ($orderItems as $item) {
46 $licenseType = $this->getLicenseType($item);
47
48 $formattedProducts[] = [
49 'product_name' => $item->post_title,
50 'variation_name' => $item->title !== $item->post_title ? $item->title : null,
51 'license_type' => $licenseType,
52 'price' => $item->unit_price,
53 'currency' => $item->order->currency,
54 'formatted_price' => $item->formatted_total,
55 'status' => $this->getProductStatus($item),
56 'order' => [
57 'id' => $item->order->id,
58 'invoice_no' => $item->order->invoice_no,
59 'status' => $item->order->status,
60 'date' => $item->order->created_at->format('Y-m-d H:i:s'),
61 'currency' => $item->order->currency,
62 'total' => number_format($item->order->total_amount / 100, 2, '.', ''),
63 'quantity' => $item->quantity
64 ]
65 ];
66 }
67
68 // Sort products by most recent order date
69 usort($formattedProducts, function ($a, $b) {
70 return strtotime($b['order']['date']) - strtotime($a['order']['date']);
71 });
72
73 // Get FluentCart customer ID
74 $fluentCartCustomer = \FluentCart\App\Models\Customer::where('user_id', $wpUserId)->first();
75 if (!$fluentCartCustomer) {
76 return $widgets;
77 }
78
79 $widgets['fct_purchases'] = [
80 'title' => __('Fluent Cart Purchases', 'fluent-support'),
81 'products' => $formattedProducts,
82 'fluent_cart_customer_id' => $fluentCartCustomer->id,
83 'summary' => [
84 'lifetime_value' => \FluentCart\App\Helpers\Helper::toDecimal($fluentCartCustomer->ltv),
85 'currency' => Arr::get($formattedProducts, '0.currency', \FluentCart\Api\CurrencySettings::get('currency')),
86 'total_purchases' => $fluentCartCustomer->purchase_count,
87 'first_purchase' => $fluentCartCustomer->first_purchase_date ? date('F j, Y', strtotime($fluentCartCustomer->first_purchase_date)) : null,
88 'last_purchase' => $fluentCartCustomer->last_purchase_date ? date('F j, Y', strtotime($fluentCartCustomer->last_purchase_date)) : null,
89 ]
90 ];
91
92 return $widgets;
93 }
94
95 // public function getFluentCartProLicenseWidget($widgets, $customer)
96 // {
97 // // Add customer's product licenses if available
98 // $licenses = $this->getCustomerProductLicenses($customer);
99
100 // if ($licenses) {
101 // $widgets['fct_license'] = [
102 // 'header' => __('Fluent Cart Product Licenses', 'fluent-support'),
103 // 'licenses' => $licenses
104 // ];
105 // }
106
107 // return $widgets;
108 // }
109
110 public function addCustomer($param)
111 {
112 $fluentCartCustomer = Arr::get($param, 'customer');
113
114 if (empty($fluentCartCustomer['email'])) {
115 return;
116 }
117
118 $customerData = [
119 'email' => $fluentCartCustomer['email'],
120 'first_name' => $fluentCartCustomer['first_name'] ?? '',
121 'last_name' => $fluentCartCustomer['last_name'] ?? '',
122 'status' => 'active'
123 ];
124
125 // Add user_id if available
126 if (!empty($fluentCartCustomer['user_id'])) {
127 $customerData['user_id'] = $fluentCartCustomer['user_id'];
128 }
129
130 // Address field mappings for efficient processing
131 $addressMappings = [
132 'city' => 'city',
133 'state' => 'state',
134 'country' => 'country',
135 'postcode' => 'zip'
136 ];
137
138 // Process primary address fields
139 foreach ($addressMappings as $source => $target) {
140 if (!empty($fluentCartCustomer[$source])) {
141 $customerData[$target] = $fluentCartCustomer[$source];
142 }
143 }
144
145 // Use billing address as fallback and add address lines
146 $billingAddress = $fluentCartCustomer['primary_billing_address'] ?? [];
147 if (!empty($billingAddress)) {
148 foreach ($addressMappings as $source => $target) {
149 if (empty($customerData[$target]) && !empty($billingAddress[$source])) {
150 $customerData[$target] = $billingAddress[$source];
151 }
152 }
153
154 foreach (['address_1' => 'address_line_1', 'address_2' => 'address_line_2'] as $source => $target) {
155 if (!empty($billingAddress[$source])) {
156 $customerData[$target] = $billingAddress[$source];
157 }
158 }
159 }
160
161 Customer::maybeCreateCustomer($customerData);
162 }
163
164 /**
165 * Get customer's product licenses from FluentCart Pro
166 *
167 * @param Customer $customer
168 * @return array|null Structured license data or null if not available
169 */
170 private function getCustomerProductLicenses($customer)
171 {
172 // Check if FluentCart Pro License model is available
173 if (!class_exists('\FluentCartPro\App\Modules\Licensing\Models\License')) {
174 return null;
175 }
176
177 try {
178 $wpUserId = $customer->user_id;
179 if (!$wpUserId) {
180 return null;
181 }
182
183 // Get FluentCart customer ID
184 $fluentCartCustomer = \FluentCart\App\Models\Customer::where('user_id', $wpUserId)->first();
185 if (!$fluentCartCustomer) {
186 return null;
187 }
188
189 // Get licenses for this customer
190 $licenses = \FluentCartPro\App\Modules\Licensing\Models\License::where('customer_id', $fluentCartCustomer->id)
191 ->with(['product'])
192 ->orderByDesc('created_at')
193 ->get()
194 ->toArray();
195
196 if (empty($licenses)) {
197 return null;
198 }
199
200 $formattedLicenses = [];
201
202 foreach ($licenses as $license) {
203 // Get product name from the data structure
204 $productName = 'Unknown Product';
205 if (isset($license['product']['post_title'])) {
206 $productName = $license['product']['post_title'];
207 }
208
209
210
211 $status = $license['status'];
212 $expirationDate = $license['expiration_date'];
213
214 // Format expiration date for tooltip
215 $expirationTooltip = '';
216 if ($expirationDate) {
217 $expirationTooltip = 'Expires: ' . date('M d, Y', strtotime($expirationDate));
218 } else {
219 $expirationTooltip = 'Expires: Lifetime';
220 }
221
222 $formattedLicenses[] = [
223 'id' => $license['id'],
224 'product_name' => $productName,
225 'status' => $status,
226 'expiration_tooltip' => $expirationTooltip,
227 'expiration_date' => $expirationDate
228 ];
229 }
230
231 return $formattedLicenses;
232
233 } catch (\Exception $e) {
234 return null;
235 }
236 }
237
238 /**
239 * Determine the license type based on order item payment type
240 *
241 * @param \FluentCart\App\Models\OrderItem $item
242 * @return string|null
243 */
244 private function getLicenseType($item)
245 {
246 switch ($item->payment_type) {
247 case 'subscription':
248 // Return 'Subscription' for internal logic but don't display it as license type
249 return 'Subscription';
250 case 'payment':
251 default:
252 // Check if it's a lifetime license based on product name or other criteria
253 if (stripos($item->post_title, 'lifetime') !== false || stripos($item->title, 'lifetime') !== false) {
254 return 'Lifetime License';
255 }
256 // Don't show license type for regular one-time purchases
257 return null;
258 }
259 }
260
261 /**
262 * Determine the product status based on order status and payment type
263 *
264 * @param \FluentCart\App\Models\OrderItem $item
265 * @return string
266 */
267 private function getProductStatus($item)
268 {
269 $orderStatus = $item->order->status;
270
271 // Return 'canceled' for multiple statuses
272 if (in_array($orderStatus, ['canceled', 'failed'])) {
273 return 'canceled';
274 }
275
276 // Return default statuses
277 $statusMap = [
278 'completed' => 'completed',
279 'processing' => 'processing',
280 'on-hold' => 'on-hold'
281 ];
282
283 return $statusMap[$orderStatus] ?? 'pending'; // Default to 'pending' if not found
284 }
285
286 private function renderCustomerPortalInFluentCartDashboard()
287 {
288 if (!function_exists('fluent_cart_api') || Helper::getBusinessSettings('enable_fc_menu') != 'yes' ) {
289 return;
290 }
291
292 fluent_cart_api()->addCustomerDashboardEndpoint('fluent-support', [
293 'title' => __('Support', 'fluent-support'),
294 'render_callback' => function () {
295 echo do_shortcode('[fluent_support_portal]');
296 },
297 'priority' => 'high',
298 'page_id_x' => apply_filters('fluent_support/fc_menu_page_id', 573),
299 ]);
300 }
301 }
302