PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.6.0
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.6.0
3.0.3 3.0.2 3.0.1 trunk 2.2.14 2.2.15 2.2.16 2.2.17 2.2.18 2.2.19 2.3.0 2.3.1 2.3.10 2.3.11 2.3.12 2.3.13 2.3.14 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 2.3.9 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.7.91 2.7.92 2.7.93 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0
commercebird / includes / classes / class-common.php
commercebird / includes / classes Last commit date
apis 7 months ago purchase-orders 9 months ago zoho-crm 7 months ago zoho-inventory 7 months ago class-api-handler-zoho.php 7 months ago class-auth-zoho.php 7 months ago class-common.php 7 months ago class-plugin.php 9 months ago class-wc-api.php 9 months ago index.php 1 year ago
class-common.php
262 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 if ( ! class_exists( 'CMBIRD_Common_Functions' ) ) {
8 /**
9 * Common functions for CommerceBird plugin integration with Zoho.
10 */
11 class CMBIRD_Common_Functions {
12 /**
13 * Constructor.
14 */
15 public function __construct() {
16 add_action( 'woocommerce_thankyou', array( $this, 'cmbird_sync_frontend_order' ) );
17 add_action( 'woocommerce_rest_insert_shop_order_object', array( $this, 'cmbird_on_insert_rest_api' ), 20, 3 );
18 add_filter( 'wcs_renewal_order_created', array( $this, 'cmbird_zi_sync_renewal_order' ), 10, 2 );
19 add_action( 'wp_ajax_zoho_admin_order_sync', array( $this, 'cmbird_zoho_order_sync' ) );
20 }
21
22 /**
23 * Sync order when it's created via the checkout.
24 *
25 * @param int $order_id The order ID.
26 * @return void
27 */
28 public function cmbird_sync_frontend_order( $order_id ) {
29 // return if the order is not coming via thank you page.
30 if ( ! is_wc_endpoint_url( 'order-received' ) ) {
31 return;
32 }
33 // Check if the transient flag is set.
34 if ( get_transient( 'cmbird_thankyou_callback_executed_' . $order_id ) ) {
35 return;
36 }
37 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
38 // First sync the customer to Zoho Inventory if the access token is set.
39 if ( is_string( $zoho_inventory_access_token ) && trim( $zoho_inventory_access_token ) !== '' ) {
40 $zi_order_class = new CMBIRD_Order_Sync_ZI();
41 $zi_order_class->cmbird_zi_sync_customer_checkout( $order_id );
42 // Use WC Action Scheduler to sync the order to Zoho Inventory.
43 $existing_schedule = as_has_scheduled_action( 'sync_zi_order', array( $order_id ) );
44 if ( ! $existing_schedule ) {
45 as_schedule_single_action( time(), 'sync_zi_order', array( $order_id ) );
46 // Set the transient flag to prevent multiple executions.
47 set_transient( 'cmbird_thankyou_callback_executed_' . $order_id, true, 60 );
48 }
49 }
50 $zoho_crm_access_token = get_option( 'cmbird_zoho_crm_access_token' );
51 // If the access token is set, sync the order to Zoho CRM.
52 if ( is_string( $zoho_crm_access_token ) && trim( $zoho_crm_access_token ) !== '' ) {
53 // Use WC Action Scheduler to sync the order to Zoho CRM.
54 $existing_schedule = as_has_scheduled_action( 'sync_zcrm_order', array( $order_id ) );
55 if ( ! $existing_schedule ) {
56 as_schedule_single_action( time(), 'sync_zcrm_order', array( $order_id ) );
57 // Set the transient flag to prevent multiple executions.
58 set_transient( 'cmbird_thankyou_callback_executed_' . $order_id, true, 60 );
59 }
60 }
61 }
62
63 /**
64 * Sync order when its scheduled via the Action Scheduler.
65 *
66 * @return void
67 */
68 public function cmbird_orders_prepare_sync() {
69 $args = func_get_args();
70 $order_id = $args[0] ?? null;
71 if ( get_option( 'cmbird_zoho_inventory_access_token' ) && $order_id ) {
72 try {
73 $zi_order_class = new CMBIRD_Order_Sync_ZI();
74 $zi_order_class->zi_order_sync( $order_id );
75 } catch ( \Throwable $e ) {
76 error_log( 'Error in cmbird_orders_prepare_sync: ' . $e->getMessage() );
77 }
78 }
79 if ( get_option( 'cmbird_zoho_crm_access_token' ) && $order_id ) {
80 try {
81 $zcrm_order_class = new CMBIRD_ZCRM_SalesOrder();
82 $zcrm_order_class->cmbird_zcrm_order_sync( $order_id );
83 } catch ( \Throwable $e ) {
84 error_log( 'Error in cmbird_orders_prepare_sync: ' . $e->getMessage() );
85 }
86 }
87 }
88
89 /**
90 * Sync order when it's created via the WC API.
91 *
92 * @param WC_Data $object Inserted object.
93 * @param WP_REST_Request $request Request object.
94 * @param boolean $is_creating True when creating object, false when updating.
95 */
96 public function cmbird_on_insert_rest_api( $object, $request, $is_creating ) {
97 // $fd = fopen(__DIR__ . '/on_insert_rest_api.txt', 'w+');
98 $request_body = $request->get_body();
99 $request_body_array = json_decode( $request_body, true );
100 $order_status = $request_body_array['status'];
101 $order_id = $object->get_id();
102
103 if ( get_option( 'cmbird_zoho_inventory_access_token' ) ) {
104 $zi_order_class = new CMBIRD_Order_Sync_ZI();
105 // Check how many keys there are in the request body array. If there are only two keys then we don't need to do anything.
106 if ( count( $request_body_array ) === 2 ) {
107 if ( in_array( $order_status, array( 'cancelled', 'wc-merged' ) ) ) {
108 $zi_order_class->salesorder_void( $order_id );
109 }
110 } else {
111 $zi_order_class->zi_order_sync( $order_id );
112 }
113 }
114 // same for Zoho CRM.
115 if ( get_option( 'cmbird_zoho_crm_access_token' ) ) {
116 $zcrm_order_class = new CMBIRD_ZCRM_SalesOrder();
117 // Check how many keys there are in the request body array. If there are only two keys then we don't need to do anything.
118 if ( count( $request_body_array ) === 2 ) {
119 return;
120 } else {
121 $zcrm_order_class->cmbird_zcrm_order_sync( $order_id );
122 }
123 }
124
125 // fclose($fd);
126 }
127
128 /**
129 * Sync Renewal Order to Zoho once it's created.
130 *
131 * @param WC_Order $renewal_order The renewal order object.
132 * @param WC_Subscription $subscription The subscription object.
133 * @return WC_Order The renewal order object.
134 */
135 public function cmbird_zi_sync_renewal_order( $renewal_order, $subscription ) {
136 $order_id = $renewal_order->get_id();
137
138 // Sync the order to Zoho CRM.
139 if ( get_option( 'cmbird_zoho_crm_access_token' ) ) {
140 $zcrm_order_class = new CMBIRD_ZCRM_SalesOrder();
141 $zcrm_order_class->cmbird_zcrm_order_sync( $order_id );
142 }
143
144 // Sync the order to Zoho Inventory.
145 if ( get_option( 'cmbird_zoho_inventory_access_token' ) ) {
146 $zi_order_class = new CMBIRD_Order_Sync_ZI();
147 $zi_order_class->zi_order_sync( $order_id );
148 }
149
150 return $renewal_order;
151 }
152
153 /**
154 * Sync a WooCommerce order to Zoho CRM and Zoho Inventory.
155 *
156 * Called via AJAX from the Zoho Order Sync admin page.
157 *
158 * @param int $order_id The order ID to sync.
159 *
160 * @return void
161 */
162 public function cmbird_zoho_order_sync( $order_id ) {
163 if ( ! $order_id && isset( $_POST['nonce'], $_POST['arg_order_data'] ) ) {
164 if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'zoho_admin_order_sync' ) ) {
165 wp_send_json_error( 'Nonce verification failed' );
166 }
167 $order_id = sanitize_text_field( wp_unslash( $_POST['arg_order_data'] ) );
168 }
169
170 if ( $order_id <= 0 ) {
171 wp_send_json_error( 'Invalid order ID.' );
172 }
173
174 // Sync the order to Zoho CRM.
175 if ( get_option( 'cmbird_zoho_crm_access_token' ) ) {
176 $zcrm_order_class = new CMBIRD_ZCRM_SalesOrder();
177 $zcrm_order_class->cmbird_zcrm_order_sync( $order_id );
178 }
179
180 // Sync the order to Zoho Inventory.
181 if ( get_option( 'cmbird_zoho_inventory_access_token' ) ) {
182 $zi_order_class = new CMBIRD_Order_Sync_ZI();
183 $zi_order_class->zi_order_sync( $order_id );
184 }
185
186 wp_send_json_success( 'Order synced successfully.' );
187 }
188
189 /**
190 * Function to clear all orphan data.
191 */
192 public function clear_orphan_data() {
193 global $wpdb;
194 // Delete orphaned product variations.
195 $deleted_variations = absint(
196 $wpdb->query(
197 "DELETE products
198 FROM {$wpdb->posts} products
199 LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent
200 WHERE wp.ID IS NULL AND products.post_type = 'product_variation';"
201 )
202 );
203 // Delete orphaned postmeta.
204 $deleted_postmeta = absint(
205 $wpdb->query(
206 "DELETE pm
207 FROM {$wpdb->postmeta} pm
208 LEFT JOIN {$wpdb->posts} wp ON wp.ID = pm.post_id
209 WHERE wp.ID IS NULL;"
210 )
211 );
212 // Return the number of deleted entries (orphaned variations + orphaned postmeta).
213 return $deleted_variations + $deleted_postmeta;
214 }
215
216 /**
217 * Get the tax class based on the tax percentage.
218 *
219 * @param float $percentage The tax percentage.
220 * @return string|false The tax class if found, or standard if not found.
221 */
222 public function get_tax_class_by_percentage( $percentage ) {
223 // $fd = fopen( __DIR__ . '/get_tax_class_by_percentage.txt', 'a+' );
224
225 global $wpdb;
226 // Determine the number of decimal places in the provided percentage.
227 $decimal_places = strlen( substr( strrchr( $percentage, '.' ), 1 ) );
228
229 // Round the percentage to the determined number of decimal places.
230 $rounded_percentage = round( $percentage, $decimal_places );
231 $tax_rates = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates WHERE ROUND(tax_rate, %d) = %f", $decimal_places, $rounded_percentage ) );
232
233 // If tax rates are found.
234 if ( $tax_rates ) {
235 // Get the tax class from the first matching tax rate.
236 $tax_class = $tax_rates[0]->tax_rate_class;
237 return $tax_class;
238 } else {
239 // Return null if no tax rates match the provided percentage.
240 return 'standard';
241 }
242 }
243
244 /**
245 * Send email to admin.
246 *
247 * @param string $subject The subject of the email.
248 * @param string $message The message body of the email.
249 *
250 * @return void
251 */
252 public function send_email( $subject, $message ) {
253 $admin_email = get_option( 'admin_email' );
254 $headers = array( 'Content-Type: text/html; charset=UTF-8' );
255
256 // Send the email.
257 wp_mail( $admin_email, $subject, $message, $headers );
258 }
259 }
260 }
261 $cmbird_common_functions = new CMBIRD_Common_Functions();
262