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