PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.2.15
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.2.15
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 / admin / includes / Actions / Sync / ExactOnlineSync.php
commercebird / admin / includes / Actions / Sync Last commit date
ExactOnlineSync.php 1 year ago ZohoCRMSync.php 1 year ago
ExactOnlineSync.php
283 lines
1 <?php
2
3 namespace CommerceBird\Admin\Actions\Sync;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 use CommerceBird\Admin\Actions\Ajax\ExactOnlineAjax;
10 use CommerceBird\Admin\Connectors\CommerceBird;
11
12 class ExactOnlineSync {
13
14
15 /**
16 * Sync data from Exact Online.
17 *
18 * @param string $type product|customer
19 * @param string $data to sync from Exact Online
20 * @param bool $import import or update
21 * @return mixed
22 */
23 public static function sync( string $type, string $data, bool $import = false ) {
24 if ( empty( $type ) ) {
25 return false;
26 }
27 $data = json_decode( $data, true );
28 if ( empty( $data ) ) {
29 return false;
30 }
31 foreach ( $data as $item ) {
32 if ( $import ) {
33 self::import( $type, $item );
34 } else {
35 self::update( $type, $item );
36 }
37 }
38 }
39 /**
40 * Import data from Exact Online.
41 *
42 * for product data will be like,
43 * {
44 * "Code":string,
45 * "Description": string,
46 * "ID": string,
47 * "IsSalesItem": bool,
48 * "PictureName": null|string,
49 * "PictureUrl": string,
50 * "StandardSalesPrice": float,
51 * "Stock": int
52 * },
53 *
54 * for Order data will be like,
55 * {
56 * "MainContact": null|string,
57 * "Email": null|string,
58 * "ID": string,
59 * "Name": string,
60 * "AddressLine1": null|string,
61 * "AddressLine2": null|string,
62 * "City": string,
63 * "Country": string,
64 * "Phone": null|string,
65 * "Postcode": string
66 * }
67 * @param string $type of provided data;
68 * @param array $data of import
69 * @return mixed
70 */
71 public static function import( string $type, array $data ) {
72 $endpoint = '';
73 $payload = array();
74 switch ( $type ) {
75 case 'product':
76 $endpoint = '/wc/v3/products';
77 $payload = array(
78 'name' => $data['Description'],
79 'sku' => $data['Code'],
80 'status' => 'publish',
81 'type' => 'simple',
82 'regular_price' => (string) $data['StandardSalesPrice'],
83 // 'stock_quantity' => (string) $data['Stock'],
84 'images' => array(
85 array(
86 'src' => $data['PictureUrl'],
87 ),
88 ),
89 'meta_data' => array(
90 array(
91 'key' => 'eo_item_id',
92
93 'value' => $data['ID'],
94 ),
95 array(
96 'key' => '_cost_price',
97 'value' => $data['CostPriceStandard'],
98 ),
99 array(
100 'key' => 'eo_unit',
101 'value' => $data['Unit'],
102 ),
103 ),
104
105 );
106 break;
107 case 'customer':
108 if ( empty( $data['Email'] ) ) {
109 break;
110 }
111 $endpoint = '/wc/v3/customers';
112 $names = explode( ' ', $data['Name'] );
113 $first_name = $names[0] ?? '';
114 $last_name = $names[1] ?? '';
115 $address = array(
116 'first_name' => $first_name,
117 'last_name' => $last_name,
118 'address_1' => $data['AddressLine1'] ?? '',
119 'address_2' => $data['AddressLine2'] ?? '',
120 'city' => $data['City'],
121 'country' => $data['Country'],
122 'postcode' => $data['Postcode'],
123 'phone' => $data['Phone'] ?? '',
124 'email' => $data['Email'],
125 );
126 $payload = array(
127 'email' => $data['Email'],
128 'first_name' => $first_name,
129 'last_name' => $last_name,
130 'billing' => $address,
131 'shipping' => $address,
132 'meta_data' => array(
133 array(
134 'key' => 'eo_account_id',
135 'value' => $data['ID'],
136 ),
137 array(
138 'key' => 'eo_contact_id',
139 'value' => $data['MainContact'] ?? '',
140 ),
141 ),
142 );
143 break;
144 default:
145 break;
146 }
147
148 if ( empty( $endpoint ) || empty( $payload ) ) {
149 return false;
150 }
151
152 $request = new \WP_REST_Request( 'POST', $endpoint );
153 $request->set_body_params( $payload );
154 rest_do_request( $request );
155 }
156 /**
157 * Update data based on Exact Online.
158 * @param string $type of provided data
159 * @param array $data to match
160 * @return void
161 */
162 public static function update( string $type, array $data ) {
163 switch ( $type ) {
164 case 'product':
165 $wc_product_id = wc_get_product_id_by_sku( $data['Code'] );
166 if ( empty( $wc_product_id ) ) {
167 $wc_product_id = self::get_product_id_by_title( $data['Description'] );
168 }
169 if ( ! empty( $wc_product_id ) ) {
170 update_post_meta( $wc_product_id, 'eo_item_id', $data['ID'] );
171 update_post_meta( $wc_product_id, '_cost_price', $data['CostPriceStandard'] );
172 update_post_meta( $wc_product_id, 'eo_unit', $data['Unit'] );
173 $wc_product = wc_get_product( $wc_product_id );
174 $wc_product->set_regular_price( $data['StandardSalesPrice'] );
175 $stock = $data['Stock'];
176 if ( is_numeric( $stock ) ) {
177 $wc_product->set_manage_stock( true );
178 $wc_product->set_stock_quantity( $data['Stock'] );
179 if ( $stock > 0 ) {
180 $wc_product->set_stock_status( 'instock' );
181 } else {
182 $backorder_status = $wc_product->backorders_allowed();
183 $status = ( $backorder_status === 'yes' ) ? 'onbackorder' : 'outofstock';
184 $wc_product->set_stock_status( $status );
185 }
186 }
187 $wc_product->save();
188 }
189 break;
190 case 'customer':
191 $user = get_user_by( 'email', $data['Email'] );
192 if ( empty( $user ) ) {
193 break;
194 }
195 $user_id = $user->ID;
196 update_user_meta( $user_id, 'eo_account_id', $data['ID'] );
197 if ( ! empty( $data['MainContact'] ) ) {
198 update_user_meta( $user_id, 'eo_contact_id', $data['MainContact'] );
199 }
200 break;
201 case 'orders':
202 $order = wc_get_order( $data['Description'] );
203 if ( empty( $order ) ) {
204 break;
205 }
206 $order->update_meta_data( 'eo_order_id', $data['OrderID'] );
207 $order->update_meta_data( 'eo_order_number', $data['OrderNumber'] );
208 $order->save();
209 break;
210 default:
211 break;
212 }
213 }
214
215 private static function get_product_id_by_title( string $product_title ) {
216 // Set up the query arguments
217 $args = array(
218 'post_type' => 'product',
219 'posts_per_page' => 1,
220 'fields' => 'ids',
221 's' => $product_title, // Search by product title
222 );
223
224 // Run the query
225 $query = new \WP_Query( $args );
226
227 // Get the product ID from the query results
228 $product_id = $query->post_count > 0 ? $query->posts[0] : 0;
229
230 // Reset post data
231 wp_reset_postdata();
232
233 return $product_id;
234 }
235
236 public static function get_payment_status_via_cron() {
237 // execute get_payment_status of ExactOnlineAjax class
238 $ajax = new ExactOnlineAjax();
239 $ajax->get_payment_status();
240 }
241
242 /**
243 * Process the payment status of the order via Exact Online.
244 * @param array $
245 * @return void
246 */
247 public static function cmbird_payment_status() {
248 $args = func_get_args();
249 $order_id = $args[0];
250 if ( empty( $order_id ) ) {
251 return;
252 }
253 $order = wc_get_order( $order_id );
254 $object = array();
255 $order_id = $order->get_id();
256 $object['OrderID'] = $order_id;
257 $customer_id = $order->get_customer_id();
258 // get the eo_account_id from the user meta
259 $object['AccountID'] = get_user_meta( $customer_id, 'eo_account_id', true );
260 $response = ( new CommerceBird() )->payment_status( $object );
261 // check response contains "Payment_Status" key
262 if ( ! isset( $response['Payment_Status'] ) ) {
263 return;
264 }
265 // if response is Paid then update the order status to completed
266 if ( 'Paid' === $response['Payment_Status'] ) {
267 // set order as paid
268 if ( $order->get_status() === 'completed' ) {
269 return;
270 }
271 $order->payment_complete();
272 $order->update_status( 'completed', __( 'Payment processed in Exact Online', 'commercebird' ) );
273 $order->save();
274 } elseif ( 'Unpaid' === $response['Payment_Status'] ) {
275 if ( $order->get_status() === 'on-hold' ) {
276 return;
277 }
278 $order->update_status( 'on-hold', __( 'Payment not processed in Exact Online', 'commercebird' ) );
279 $order->save();
280 }
281 }
282 }
283