PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.3.7
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.3.7
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 / zoho-inventory / class-order-sync.php
commercebird / includes / classes / zoho-inventory Last commit date
class-categories.php 1 year ago class-import-image.php 1 year ago class-import-items.php 1 year ago class-import-price-list.php 1 year ago class-multi-currency.php 1 year ago class-order-sync.php 1 year ago class-product.php 1 year ago class-users-contact.php 1 year ago index.php 1 year ago
class-order-sync.php
722 lines
1 <?php
2
3 /**
4 * Class for handling Zoho Inventory order sync related functions.
5 */
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 class CMBIRD_Order_Sync_ZI {
11
12
13
14 private $location_id;
15 private $parent_location_id;
16 private $enable_order_status;
17 private $enable_auto_number;
18 private $order_prefix;
19 private $custom_fields;
20 private $include_tax;
21
22 /**
23 * Initialize the class.
24 */
25 public function __construct() {
26 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
27 if ( ! empty( $zoho_inventory_access_token ) ) {
28 add_action( 'woocommerce_rest_insert_shop_order_object', array( $this, 'on_insert_rest_api' ), 20, 3 );
29 add_filter( 'wcs_renewal_order_created', array( $this, 'cmbird_zi_sync_renewal_order' ), 10, 2 );
30 add_action( 'wp_ajax_zoho_admin_order_sync', array( $this, 'zi_order_sync' ) );
31 add_action( 'woocommerce_update_order', array( $this, 'salesorder_void' ) );
32 add_action( 'woocommerce_thankyou', array( $this, 'zi_sync_frontend_order' ) );
33 // get options
34 $this->location_id = get_option( 'cmbird_zoho_location_id_status' );
35 $this->parent_location_id = get_option( 'cmbird_zoho_parent_location_id_status' );
36 $this->enable_order_status = get_option( 'cmbird_zoho_enable_order_status_status' );
37 $this->enable_auto_number = get_option( 'cmbird_zoho_enable_auto_number_status' );
38 $this->order_prefix = get_option( 'cmbird_zoho_order_prefix_status' );
39 $this->custom_fields = json_decode( get_option( 'cmbird_wootozoho_custom_fields' ), true );
40 $this->include_tax = get_option( 'woocommerce_prices_include_tax' ) === 'yes';
41 } else {
42 return;
43 }
44 }
45
46 /**
47 * Sync order when it's created via the checkout.
48 */
49 public function zi_sync_frontend_order( $order_id ) {
50 // return if the order is not coming via thank you page
51 if ( ! is_wc_endpoint_url( 'order-received' ) ) {
52 return;
53 }
54 // Check if the transient flag is set
55 if ( get_transient( 'cmbird_thankyou_callback_executed_' . $order_id ) ) {
56 return;
57 }
58 // First sync the customer to Zoho Inventory
59 $this->cmbird_zi_sync_customer_checkout( $order_id );
60
61 // Use WC Action Scheduler to sync the order to Zoho Inventory
62 $existing_schedule = as_has_scheduled_action( 'sync_zi_order', array( $order_id ) );
63 if ( ! $existing_schedule ) {
64 as_schedule_single_action( time(), 'sync_zi_order', array( $order_id ) );
65 // Set the transient flag to prevent multiple executions
66 set_transient( 'cmbird_thankyou_callback_executed_' . $order_id, true, 60 );
67 }
68 }
69 /**
70 * Sync order when its scheduled via the Action Scheduler.
71 *
72 * @param int $order_id Order ID.
73 * @return void
74 */
75 public function zi_orders_prepare_sync() {
76 $args = func_get_args();
77 $order_id = $args[0];
78 if ( ! get_option( 'cmbird_zoho_inventory_access_token' ) || ! $order_id ) {
79 return;
80 }
81 $this->zi_order_sync( $order_id );
82 }
83
84 /**
85 * Sync order when it's created via the WC API.
86 *
87 * @param WC_Data $object Inserted object.
88 * @param WP_REST_Request $request Request object.
89 * @param boolean $creating True when creating object, false when updating.
90 */
91 public function on_insert_rest_api( $object, $request, $is_creating ) {
92 if ( empty( get_option( 'cmbird_zoho_inventory_access_token' ) ) ) {
93 return;
94 }
95 // $fd = fopen(__DIR__ . '/on_insert_rest_api.txt', 'w+');
96 $request_body = $request->get_body();
97 $request_body_array = json_decode( $request_body, true );
98 $order_status = $request_body_array['status'];
99 $order_id = $object->get_id();
100
101 // 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.
102 if ( count( $request_body_array ) === 2 ) {
103 if ( in_array( $order_status, array( 'cancelled', 'wc-merged' ) ) ) {
104 $this->salesorder_void( $order_id );
105 }
106 } else {
107 $this->zi_order_sync( $order_id );
108 }
109 // fclose($fd);
110 }
111
112 /**
113 * Sync Renewal Order to Zoho once it's created.
114 */
115 public function cmbird_zi_sync_renewal_order( $renewal_order, $subscription ) {
116 if ( empty( get_option( 'cmbird_zoho_inventory_access_token' ) ) ) {
117 return $renewal_order;
118 }
119
120 $order_id = $renewal_order->get_id();
121 $this->zi_order_sync( $order_id );
122
123 return $renewal_order;
124 }
125
126 /**
127 * Function to map customer on checkout before placing order
128 * @param int $order_id Order ID.
129 *
130 */
131 public function cmbird_zi_sync_customer_checkout( $order_id ) {
132 // $fd = fopen( __DIR__ . '/cmbird_zi_sync_customer_checkout.txt', 'w+' );
133
134 $order = wc_get_order( $order_id );
135 $userid = $order->get_user_id();
136 $user_company = $order->get_billing_company();
137 $user_email = $order->get_billing_email();
138 $zi_customer_id = get_user_meta( $userid, 'zi_contact_id', true );
139
140 // Get currency code of the order
141 $currency_id = intval( get_user_meta( $userid, 'zi_currency_id', true ) );
142 if ( empty( $currency_id ) ) {
143 $currency_code = $order->get_currency();
144 $multi_currency_handle = new CMBIRD_Multicurrency_Zoho();
145 $currency_id = $multi_currency_handle->zoho_currency_data( $currency_code, $userid );
146 }
147
148 if ( $zi_customer_id ) {
149 $zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );
150 $zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
151 $get_url = $zoho_inventory_url . 'inventory/v1/contacts/' . $zi_customer_id . '/?organization_id=' . $zoho_inventory_oid;
152
153 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
154 $json = $execute_curl_call_handle->execute_curl_call_get( $get_url );
155
156 // fwrite($fd,PHP_EOL.'customer_json: '.print_r($json, true));
157
158 $code = $json->code;
159 if ( 0 !== $code || '0' !== $code ) {
160 delete_user_meta( $userid, 'zi_contact_id' );
161 delete_user_meta( $userid, 'zi_billing_address_id' );
162 delete_user_meta( $userid, 'zi_primary_contact_id' );
163 delete_user_meta( $userid, 'zi_shipping_address_id' );
164 delete_user_meta( $userid, 'zi_created_time' );
165 delete_user_meta( $userid, 'zi_last_modified_time' );
166 $zi_customer_id = '';
167 }
168 }
169
170 /**
171 * syncing customer if its not in Zoho yet
172 */
173 if ( ! $zi_customer_id ) {
174
175 // First check based on customer email address
176 $zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );
177 $zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
178 // fwrite($fd,PHP_EOL.'$user_mail : '.$user_email);
179 $url = $zoho_inventory_url . 'inventory/v1/contacts?organization_id=' . $zoho_inventory_oid . '&email=' . $user_email;
180
181 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
182 $json = $execute_curl_call_handle->execute_curl_call_get( $url );
183
184 $code = $json->code;
185 $message = $json->message;
186 if ( 0 === $code || '0' === $code ) {
187 // fwrite($fd, PHP_EOL . 'customer_json: ' . print_r($json, true));
188 if ( empty( $json->contacts ) ) {
189 // Second check based on Company Name
190 if ( $user_company ) {
191 $company_name = str_replace( ' ', '%20', $user_company );
192 $url = $zoho_inventory_url . 'inventory/v1/contacts?organization_id=' . $zoho_inventory_oid . '&filter_by=Status.Active&search_text=' . $company_name;
193
194 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
195 $json = $execute_curl_call_handle->execute_curl_call_get( $url );
196
197 $code = $json->code;
198 if ( 0 === $code || '0' === $code ) {
199 if ( empty( $json->contacts ) ) {
200 $contact_class_handle = new CMBIRD_Contact_ZI();
201 $zi_customer_id = $contact_class_handle->cmbird_contact_create_function( $userid );
202 } else {
203 foreach ( $json->contacts[0] as $key => $value ) {
204 if ( 'contact_id' === $key ) {
205 $zi_customer_id = $value;
206 update_user_meta( $userid, 'zi_contact_id', $zi_customer_id );
207 }
208 }
209 $contact_class_handle = new CMBIRD_Contact_ZI();
210 $zi_customer_id = $contact_class_handle->cmbird_create_contact_person( $userid );
211 }
212 }
213 } else {
214 $contact_class_handle = new CMBIRD_Contact_ZI();
215 $zi_customer_id = $contact_class_handle->cmbird_contact_create_function( $userid );
216 }
217 } else {
218 // fwrite($fd,PHP_EOL.'Contacts : '.print_r($json->contacts,true));
219 foreach ( $json->contacts[0] as $key => $value ) {
220 if ( 'contact_id' === $key ) {
221 $zi_customer_id = $value;
222 update_user_meta( $userid, 'zi_contact_id', $zi_customer_id );
223 }
224 }
225 }
226 }
227 // Http request not processed properly.
228 // echo $message;
229 return $zi_customer_id;
230 } else {
231 $zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );
232 $zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
233 $get_url = $zoho_inventory_url . 'inventory/v1/contacts/' . $zi_customer_id . '/contactpersons/?organization_id=' . $zoho_inventory_oid;
234
235 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
236 $contactpersons_response = $execute_curl_call_handle->execute_curl_call_get( $get_url );
237
238 // fwrite( $fd, PHP_EOL . 'Contactpersons: ' . print_r($contactpersons_response, true) );
239
240 // first check within contactpersons endpoint and then map it with that contactperson if email-id matches
241 if ( 0 === $contactpersons_response->code || '0' === $contactpersons_response->code ) {
242 if ( ! empty( $contactpersons_response->contact_persons ) ) {
243 foreach ( $contactpersons_response->contact_persons as $key => $contact_persons ) {
244 $person_email = trim( $contact_persons->email );
245 if ( trim( $user_email ) === $person_email ) {
246 /* Match Contact */
247 $contactid = $contact_persons->contact_person_id;
248 update_user_meta( $userid, 'zi_contactperson_id_' . $key, $contactid );
249 if ( true === $contact_persons->is_primary_contact || 1 === $contact_persons->is_primary_contact ) {
250 $contact_class_handle = new CMBIRD_Contact_ZI();
251 $contact_class_handle->cmbird_contact_update_function( $userid, $order_id );
252 } else {
253 $contact_class_handle = new CMBIRD_Contact_ZI();
254 $contact_class_handle->cmbird_update_contact_person( $userid, $order_id );
255 }
256 }
257 }
258 } else {
259 $get_url = $zoho_inventory_url . 'inventory/v1/contacts/' . $zi_customer_id . '/?organization_id=' . $zoho_inventory_oid;
260 $contact_res = $execute_curl_call_handle->execute_curl_call_get( $get_url );
261 if ( ( 0 === $contact_res->code || '0' === $contact_res->code ) && ! empty( $contact_res->contact ) ) {
262 foreach ( $contact_res as $contact_ ) {
263 if ( trim( $contact_->email ) == trim( $user_email ) ) {
264 // fwrite( $fd, PHP_EOL . 'Inside cmbird_contact_update_function' );
265 $contact_class_handle = new CMBIRD_Contact_ZI();
266 $contact_class_handle->cmbird_contact_update_function( $userid, $order_id );
267 } else {
268 // fwrite( $fd, PHP_EOL . 'Inside cmbird_create_contact_person' );
269 $contact_class_handle = new CMBIRD_Contact_ZI();
270 $contact_class_handle->cmbird_create_contact_person( $userid );
271 }
272 }
273 }
274 }
275 }
276 // fwrite( $fd, PHP_EOL . 'No contactpersons ' );
277 }
278 // fclose( $fd );
279 }
280
281 /**
282 * Function for admin zoho sync call.
283 *
284 * @param int $order_id Order ID.
285 */
286 public function zi_order_sync( $order_id ) {
287 if ( ! $order_id && isset( $_POST['nonce'], $_POST['arg_order_data'] ) ) {
288 if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'zoho_admin_order_sync' ) ) {
289 wp_send_json_error( 'Nonce verification failed' );
290 }
291 $order_id = sanitize_text_field( wp_unslash( $_POST['arg_order_data'] ) );
292 }
293
294 $order = wc_get_order( $order_id );
295 if ( ! $order ) {
296 return;
297 }
298
299 $current_time = time();
300 $last_time = $order->get_meta( 'zi_last_order_sync_time', true );
301 if ( ! empty( $last_time ) && $current_time - $last_time < 60 ) {
302 return;
303 }
304
305 $zi_sales_order_id = $order->get_meta( 'zi_salesorder_id' );
306 $userid = $order->get_user_id();
307 $user_email = get_user_meta( $userid, 'billing_email', true );
308
309 if ( empty( $userid ) && empty( $user_email ) ) {
310 $order->add_order_note( 'Zoho Order Sync: guest orders are not supported' );
311 $order->save();
312 return;
313 }
314
315 $customer_id = get_user_meta( $userid, 'zi_contact_id', true );
316 $billing_id = get_user_meta( $userid, 'zi_billing_address_id', true );
317 $shipping_id = get_user_meta( $userid, 'zi_shipping_address_id', true );
318
319 if ( empty( $customer_id ) ) {
320 $customer_id = $this->cmbird_zi_sync_customer_checkout( $order_id );
321 } else {
322 $contact_class = new CMBIRD_Contact_ZI();
323 $contact_class->cmbird_contact_update_function( $userid, $order_id );
324 }
325
326 $line_items = $this->build_line_items( $order );
327 if ( empty( $line_items ) ) {
328 return;
329 }
330
331 $pdt = array(
332 'customer_id' => $customer_id,
333 'date' => $order->get_date_created()->format( 'Y-m-d' ),
334 'line_items' => $line_items,
335 'is_discount_before_tax' => true,
336 'discount_type' => 'item_level',
337 'price_precision' => '2',
338 'notes' => preg_replace( '/[^A-Za-z0-9\-]/', ' ', $order->get_customer_note() ),
339 'billing_address_id' => $billing_id,
340 'shipping_address_id' => $shipping_id,
341 'delivery_method' => $order->get_shipping_method(),
342 'is_inclusive_tax' => $this->include_tax,
343 'shipping_charge' => $this->get_shipping_total( $order ),
344 'order_status' => $this->enable_order_status ? 'draft' : 'confirmed',
345 );
346
347 if ( $this->parent_location_id ) {
348 $pdt['location_id'] = $this->parent_location_id;
349 }
350
351 $shipping_tax_id = $this->get_shipping_tax_id( $order );
352 if ( $shipping_tax_id ) {
353 $pdt['shipping_charge_tax_id'] = $shipping_tax_id;
354 }
355
356 $fees = $this->get_order_fees( $order );
357 $pdt = array_merge( $pdt, $fees );
358
359 $pdt['custom_fields'] = $this->prepare_custom_fields( $order );
360 $reference = $this->prepare_reference_number( $order );
361
362 if ( $this->enable_auto_number ) {
363 $pdt['reference_number'] = $reference;
364 } else {
365 $pdt['salesorder_number'] = $order->get_id();
366 }
367
368 $userid = $order->get_user_id();
369 $gst_no = get_user_meta( $userid, 'gst_no', true );
370 $gst_treatment = get_user_meta( $userid, 'gst_treatment', true );
371 if ( $gst_no ) {
372 $pdt['gst_no'] = $gst_no;
373 $pdt['gst_treatment'] = $gst_treatment;
374 }
375
376 $response_msg = $zi_sales_order_id ? $this->single_saleorder_zoho_inventory_update( $order_id, $zi_sales_order_id, wp_json_encode( $pdt ) ) : $this->single_saleorder_zoho_inventory( wp_json_encode( $pdt ), $order_id );
377
378 $order->update_meta_data( 'zi_body_request', wp_json_encode( $pdt ) );
379 $order->update_meta_data( 'zi_salesorder_id', $response_msg['zi_salesorder_id'] );
380 $order->update_meta_data( 'zi_last_order_sync_time', $current_time );
381 $order->add_order_note( 'Zoho Order Sync: ' . $response_msg['message'] );
382 $order->save();
383 }
384
385 private function build_line_items( $order ) {
386 $items = array();
387 foreach ( $order->get_items() as $item_id => $item ) {
388 $product = $item->get_product();
389 if ( ! $product ) {
390 continue;
391 }
392 $name = $item->get_name();
393 $meta = $item->get_formatted_meta_data();
394 $desc = '';
395 if ( ! empty( $meta ) ) {
396 foreach ( $meta as $meta_value ) {
397 $desc .= $meta_value->display_key . ': ' . wp_strip_all_tags( $meta_value->display_value ) . ' ';
398 }
399 $desc = sanitize_text_field( trim( $desc ) );
400 }
401
402 $quantity = $item->get_quantity();
403 $subtotal = $item->get_subtotal();
404 $total = $item->get_total();
405 $rate = $subtotal / max( 1, $quantity );
406 $discount = $subtotal > $total ? $subtotal - $total : 0;
407
408 $tax_data = $item->get_taxes();
409 $tax_id = '';
410 $tax_percent = 0;
411 if ( ! empty( $tax_data['subtotal'] ) ) {
412 $tax_rate_id = key( $tax_data['subtotal'] );
413 $tax_percent = WC_Tax::_get_tax_rate( $tax_rate_id )['tax_rate'];
414 $tax_id = $this->zi_get_tax_id( $tax_percent );
415 if ( $this->include_tax ) {
416 $rate += $rate * ( $tax_percent / 100 );
417 $discount += $discount * ( $tax_percent / 100 );
418 }
419 }
420
421 $line = array(
422 'item_id' => get_post_meta( $product->get_id(), 'zi_item_id', true ),
423 'name' => $name,
424 'description' => $desc,
425 'quantity' => $quantity,
426 'rate' => round( $rate, 2 ),
427 );
428
429 if ( $discount > 0 ) {
430 $line['discount'] = round( $discount, 2 );
431 }
432 if ( $tax_id ) {
433 $line['tax_percentage'] = $tax_percent;
434 $line['tax_id'] = $tax_id;
435 }
436 // add location id if set
437 if ( $this->location_id ) {
438 $line['location_id'] = $this->location_id;
439 }
440 $items[] = $line;
441 }
442 return $items;
443 }
444
445 private function get_shipping_total( $order ) {
446 return round( $order->get_shipping_total() + $order->get_shipping_tax(), 2 );
447 }
448
449 private function get_shipping_tax_id( $order ) {
450 $shipping_total = $order->get_shipping_total();
451 $shipping_tax = $order->get_shipping_tax();
452 if ( $shipping_total > 0 && $shipping_tax > 0 ) {
453 $percent = ( $shipping_tax / $shipping_total ) * 100;
454 return $this->zi_get_tax_id( round( $percent, 2 ) );
455 }
456 return '';
457 }
458
459 private function get_order_fees( $order ) {
460 $fees = $order->get_fees();
461 $data = array();
462 foreach ( $fees as $fee ) {
463 $amount = $fee->get_total();
464 if ( $amount > 0 ) {
465 $data['adjustment'] = $amount;
466 $data['adjustment_description'] = $fee->get_name();
467 }
468 }
469 return $data;
470 }
471
472 private function prepare_custom_fields( $order ) {
473 $fields = array();
474 if ( is_array( $this->custom_fields ) ) {
475 foreach ( $this->custom_fields as $meta_key => $label ) {
476 $fields[] = array(
477 'label' => $label,
478 'value' => $order->get_meta( $meta_key ),
479 );
480 }
481 }
482 return $fields;
483 }
484
485 private function prepare_reference_number( $order ) {
486 $transaction_id = $order->get_transaction_id();
487 if ( empty( $transaction_id ) ) {
488 $transaction_id = $order->get_meta( '_order_number', true );
489 }
490 if ( class_exists( 'WCJ_Order_Numbers' ) || class_exists( 'WC_Seq_Order_Number_Pro' ) ) {
491 return $this->order_prefix . $transaction_id;
492 }
493 if ( ! empty( $this->order_prefix ) ) {
494 return $this->order_prefix . '-' . $order->get_id();
495 }
496 return $order->get_id();
497 }
498
499 /**
500 * Void the sales order if cancelled in WooCommerce.
501 *
502 * @param int $order_id Order ID.
503 */
504 public function salesorder_void( $order_id ) {
505 if ( ! $order_id ) {
506 return;
507 }
508 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
509 if ( empty( $zoho_inventory_access_token ) ) {
510 return;
511 }
512
513 $order = wc_get_order( $order_id );
514 // return if order is already voided
515 if ( $order->get_meta( 'zi_salesorder_void', true ) ) {
516 return;
517 }
518 $order_status = $order->get_status();
519
520 if ( 'cancelled' === $order_status || 'wc-merged' === $order_status ) {
521 $zi_sales_order_id = $order->get_meta( 'zi_salesorder_id', true );
522 $zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );
523 $zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
524
525 $url = $zoho_inventory_url . 'inventory/v1/salesorders/' . $zi_sales_order_id . '/status/void?organization_id=' .
526 $zoho_inventory_oid;
527 $data = '';
528 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
529 $json = $execute_curl_call_handle->execute_curl_call_post( $url, $data );
530
531 $errmsg = $json->message;
532 $code = $json->code;
533 if ( '0' === $code || 0 === $code ) {
534 // Add order meta key "zi_salesorder_void" to true
535 $order->update_meta_data( 'zi_salesorder_void', true );
536 $order->add_order_note( 'Zoho Order Void: ' . $errmsg );
537 $order->save();
538 return;
539 }
540 } else {
541 return;
542 }
543 }
544
545 /**
546 * Sync order from Woo to Zoho.
547 *
548 * @param string $pdt1 JSON string
549 * @param int $order_id Order ID.
550 * @return string Error message
551 */
552 public function single_saleorder_zoho_inventory( $pdt1, $order_id ) {
553 //start logging
554 // $fd = fopen( __DIR__ . '/order-sync-backend.txt', 'w+' );
555
556 $zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );
557 $zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
558
559 $data = array(
560 'JSONString' => $pdt1,
561 'organization_id' => $zoho_inventory_oid,
562 );
563
564 //logging
565 // fwrite($fd, PHP_EOL . 'Data log : ' . print_r($data, true));
566
567 $enabled_auto_no = get_option( 'cmbird_zoho_enable_auto_number_status' );
568 $ignore_auto_no = ( $enabled_auto_no ) ? 'false' : 'true';
569 $url = $zoho_inventory_url . 'inventory/v1/salesorders?ignore_auto_number_generation=' . $ignore_auto_no;
570
571 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
572 $json = $execute_curl_call_handle->execute_curl_call_post( $url, $data );
573
574 // fwrite( $fd, PHP_EOL . 'Data log : ' . print_r( $json, true ) );
575 $response = array();
576 $code = $json->code;
577 $errmsg = $json->message;
578 // fwrite($fd, PHP_EOL . 'Code : ' . $code);
579
580 if ( '0' === $code || 0 === $code ) {
581 foreach ( $json->salesorder as $key => $value ) {
582
583 if ( 'salesorder_id' === $key ) {
584 $response['zi_salesorder_id'] = $value;
585 // $order->add_meta_data('zi_salesorder_id', $value, true);
586 }
587 }
588 } else {
589 // send email to admin with the error message
590 // create message that contains the error message and order id
591 $message = 'Error in Zoho Inventory Order Sync: ' . $errmsg;
592 // append the link to the order edit page
593 $message .= '<br><br><a href="' . admin_url( 'admin.php?page=wc-orders&action=edit&id=' . $order_id ) . '">Click here to view the order in WP Admin</a>';
594 $message .= '<br><br>Order ID: ' . $order_id;
595 $message .= '<br><br>Request Body: ' . $pdt1;
596 $class_common = new CMBIRD_Common_Functions();
597 $class_common->send_email( 'Error in Zoho Order Sync', $message );
598 }
599 $response['message'] = $errmsg;
600 // fclose( $fd );
601
602 return $response;
603 }
604
605 /**
606 * Function for updating single sales order.
607 *
608 * @param int $order_id Order ID.
609 * @param string $zi_sales_order_id
610 * @param string $pdt1 JSON string
611 * @return string Error message
612 */
613 public function single_saleorder_zoho_inventory_update( $order_id, $zi_sales_order_id, $pdt1 ) {
614 // $fd = fopen( __DIR__. '/single_saleorder_update.txt', 'w+' );
615
616 $response = array();
617 $zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );
618 $zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
619
620 $url = $zoho_inventory_url . 'inventory/v1/salesorders/' . $zi_sales_order_id;
621 $data = array(
622 'JSONString' => $pdt1,
623 'organization_id' => $zoho_inventory_oid,
624 );
625
626 $order = wc_get_order( $order_id );
627 // fwrite($fd, PHP_EOL. print_r($data, true)); //logging response
628 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
629 $json = $execute_curl_call_handle->execute_curl_call_put( $url, $data );
630
631 // $code = $json->code;
632 $errmsg = $json->message;
633 $response['message'] = $errmsg;
634 $response['zi_salesorder_id'] = $zi_sales_order_id;
635
636 // echo '<pre>'; print_r($errmsg);
637
638 $package_id = $order->get_meta( 'zi_package_id', true );
639
640 if ( ! empty( $package_id ) ) {
641 // fwrite($fd, PHP_EOL. 'inside package exists'); //logging response
642 foreach ( $json->salesorder as $key => $value ) {
643 if ( 'date' === $key ) {
644 $ship_date = $value;
645 }
646
647 if ( 'line_items' === $key ) {
648 foreach ( $value as $kk => $vv ) {
649 $line_items[] = '{"so_line_item_id": "' . $vv->line_item_id . '","quantity": "' . $vv->quantity . '"}';
650 }
651 $impot = implode( ',', $line_items );
652
653 $json_package = '"date": "' . $ship_date . '","line_items": [' . $impot . ']';
654
655 $url_package = $zoho_inventory_url . 'inventory/v1/packages/' . $package_id;
656 $data3 = array(
657 'JSONString' => '{' . $json_package . '}',
658 'organization_id' => $zoho_inventory_oid,
659 );
660
661 $res_package = $execute_curl_call_handle->execute_curl_call_put( $url_package, $data3 );
662 }
663 }
664 }
665 // fclose( $fd ); //end of logging
666 return $response;
667 }
668
669 /**
670 * Function to get all Zoho Taxes.
671 *
672 * @param int $percentage Tax percentage.
673 * @return string Tax ID.
674 */
675 protected function zi_get_tax_id( $percentage ) {
676 // $fd = fopen( __DIR__ . '/zi_get_tax_id.txt', 'a+' );
677 // get all options that contain zoho_inventory_tax_rate_ in the name using global $wpdb.
678 global $wpdb;
679 $zoho_tax_rates = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE 'cmbird_zoho_inventory_tax_rate_%'" );
680 $input_tax_percentage = floor( $percentage * 10 ) / 10;
681 // fwrite( $fd, PHP_EOL . 'Input Tax Percentage: ' . $input_tax_percentage );
682 $tax_id = '';
683 // for each zoho_tax_rate, check if the tax percentage matches the input percentage. The percentage at the end of the value e.g. 69497000002395146##BTW@@Hoog Exclusief##tax##21
684 foreach ( $zoho_tax_rates as $zoho_tax_rate ) {
685 $tax_rate = explode( '##', $zoho_tax_rate->option_value );
686 $tax_percentage = $tax_rate[3];
687 // Round the stored tax percentage to one decimal place for comparison
688 $stored_tax_percentage = round( $tax_percentage, 1 );
689 // Compare the rounded tax percentages with a tolerance for floating-point precision errors
690 if ( abs( $stored_tax_percentage - $input_tax_percentage ) < 0.01 ) {
691 $tax_id = $tax_rate[0];
692 break;
693 }
694 }
695 return $tax_id;
696 }
697
698 /**
699 * TODO: Get Order Transaction Fees
700 *
701 * @param int $order_id Order ID.
702 * @return float Transaction fees
703 */
704 protected function get_transaction_fees( $order_id ) {
705 $order = wc_get_order( $order_id );
706 switch ( true ) {
707 // get fees from Stripe, if exists
708 case $fees = $order->get_meta( '_stripe_fee' ):
709 break;
710 // get fees from Paypal, if exists
711 case ( $fees = $order->get_meta( '_paypal_transaction_fee' ) ) !== null:
712 break;
713 // otherwise fee is 0
714 default:
715 $fees = 0;
716 break;
717 }
718 return $fees;
719 }
720 }
721 $CMBIRD_Order_Sync_ZI = new CMBIRD_Order_Sync_ZI();
722