PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.3.14
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.3.14
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 / apis / class-api-for-woo-order.php
commercebird / includes / classes / apis Last commit date
class-api-for-cmbird.php 1 year ago class-api-for-exact-webhooks.php 1 year ago class-api-for-product-webhook.php 1 year ago class-api-for-shipping-status.php 1 year ago class-api-for-woo-order.php 1 year ago class-api-for-zoho-inventory.php 1 year ago class-commercebird-list-items-api-controller.php 1 year ago class-commercebird-media-api-controller.php 1 year ago class-commercebird-metadata-controller.php 1 year ago index.php 1 year ago trait-api-permission.php 11 months ago
class-api-for-woo-order.php
256 lines
1 <?php
2
3 namespace CommerceBird\API;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 use CommerceBird\Admin\Traits\LogWriter;
10 use WP_REST_Response;
11
12 class CreateOrderWebhook {
13
14 use Api;
15 use LogWriter;
16
17 private static string $endpoint = 'create-woo-order';
18
19
20 public function __construct() {
21 register_rest_route(
22 self::$namespace,
23 self::$endpoint,
24 array(
25 'methods' => 'POST',
26 'callback' => array( $this, 'handle' ),
27 'permission_callback' => array( $this, 'permission_check' ),
28 )
29 );
30 }
31
32 /**
33 * @param $address
34 *
35 * @return array
36 */
37 public function format_address( $address ): array {
38 if ( array_key_exists( 'attention', $address ) ) {
39 $names = explode( ' ', $address['attention'] );
40 $first_name = $names[0] ?? '';
41 $last_name = $names[1] ?? '';
42 }
43 return array(
44 'first_name' => $first_name ?? '',
45 'last_name' => $last_name ?? '',
46 'address_1' => $address['address'] ?? '',
47 'address_2' => $address['street2'] ?? '',
48 'city' => $address['city'] ?? '',
49 'state' => $address['state_code'] ?? '',
50 'postcode' => $address['zip'] ?? '',
51 'country' => $address['country_code'] ?? '',
52 'phone' => $address['phone'] ?? '',
53 );
54 }
55
56 private function process( array $order_data ): WP_REST_Response {
57 $response = new WP_REST_Response();
58
59 if ( empty( $order_data ) || empty( $order_data['salesorder'] ) ) {
60 $response->set_data( $this->empty_response );
61 $response->set_status( 404 );
62 return $response;
63 }
64
65 $allowed_keys = array(
66 'salesorder_id',
67 'salesorder_number',
68 'customer_id',
69 'billing_address',
70 'shipping_address',
71 'delivery_method',
72 'currency_code',
73 'line_items',
74 'contact_person_details',
75 'shipping_charges',
76 'order_status',
77 'paid_status',
78 'discount',
79 'discount_total',
80 'notes',
81 );
82
83 $order_data = array_intersect_key( $order_data['salesorder'], array_flip( $allowed_keys ) );
84 $billing_address = $this->format_address( $order_data['billing_address'] );
85 $shipping_address = $this->format_address( $order_data['shipping_address'] );
86 if ( isset( $order_data['contact_person_details'][0]['email'] ) ) {
87 $customer_data = $order_data['contact_person_details'][0];
88 $customer_mail = $customer_data['email'];
89 $customer = get_user_by( 'email', $customer_mail );
90 if ( empty( $customer ) ) {
91 $customer_id = wc_create_new_customer( $customer_mail );
92 $customer = get_user_by( 'id', $customer_id );
93 }
94 }
95
96 if ( empty( $order_data['line_items'] ) ) {
97 // translators: 1: order number, 2: Store name
98 $message = sprintf( __( 'Zoho order #%1$s could not be created in your store %2$s because of missing line items.', 'commercebird' ), $order_data['salesorder_number'], get_bloginfo( 'name' ) );
99 cmbird_error_log_api_email( __( 'Zoho Order Sync', 'commercebird' ), $message );
100 $response->set_status( 500 );
101 $response->set_data( $message );
102 return $response;
103 }
104
105 $line_items = $this->get_items( $order_data['line_items'] );
106
107 if ( ! empty( $line_items['not_found'] ) ) {
108 // translators: 1: order number, 2: Store name, 3: missing items
109 $message = sprintf( __( 'Zoho order #%1$s could not be created in your store %2$s because of missing items: %3$s', 'commercebird' ), $order_data['salesorder_number'], get_bloginfo( 'name' ), implode( ', ', $line_items['not_found'] ) );
110 cmbird_error_log_api_email( __( 'Zoho Order Sync', 'commercebird' ), $message );
111 $response->set_status( 500 );
112 $response->set_data( $message );
113 return $response;
114 }
115 // create shipping object
116 $shipping = new \WC_Order_Item_Shipping();
117 $shipping->set_method_title( $order_data['delivery_method'] );
118 $shipping->set_total( $order_data['shipping_charges']['item_total'] );
119 $id = $this->get_order_id( $order_data['salesorder_id'] );
120 $existing_order = wc_get_order( $id );
121 if ( ! empty( $existing_order ) ) {
122 $existing_order->set_address( $shipping_address, 'shipping' );
123
124 // Get existing order items
125 $order_items = array_column( $order_data['line_items'], 'quantity', 'sku' );
126 $existing_order->remove_order_items( 'line_item' );
127 foreach ( $order_items as $sku => $quantity ) {
128 $product_id = wc_get_product_id_by_sku( $sku );
129 if ( empty( $product_id ) ) {
130 continue;
131 }
132 $product = wc_get_product( $product_id );
133 if ( empty( $product_id ) ) {
134 continue;
135 }
136 $existing_order->add_product( $product, $quantity );
137 }
138 // Save the changes to the order
139 $existing_order->set_customer_note( isset( $order_data['notes'] ) ? $order_data['notes'] : '' );
140 $existing_order->update_status( $this->map_status( $order_data['paid_status'] ) );
141 $existing_order->calculate_totals();
142 $existing_order->save();
143 wc_delete_shop_order_transients( $existing_order );
144 $response->set_data(
145 array(
146 'id' => $existing_order->get_id(),
147 'items' => array_map(
148 function ($item) {
149 return array(
150 'product_id' => $item->get_product_id(),
151 'quantity' => $item->get_quantity(),
152 'price' => $item->get_total(),
153 );
154 },
155 $existing_order->get_items()
156 ),
157 'total' => $existing_order->get_total(),
158 )
159 );
160 } else {
161 $order = wc_create_order();
162 if ( $customer ) {
163 $order->set_customer_id( $customer->ID );
164 }
165 foreach ( $order_data['line_items'] as $order_data_item ) {
166 $product_id = wc_get_product_id_by_sku( $order_data_item['sku'] );
167 if ( empty( $product_id ) ) {
168 continue;
169 }
170 $product = wc_get_product( $product_id );
171 if ( empty( $product_id ) ) {
172 continue;
173 }
174 $order->add_product( $product, $order_data_item['quantity'] );
175 }
176 $order->set_address( $billing_address, 'billing' );
177 $order->set_address( $shipping_address, 'shipping' );
178 $order->set_currency( $order_data['currency_code'] );
179 $order->set_status( $this->map_status( $order_data['paid_status'] ) );
180 $order->set_discount_total( $order_data['discount'] );
181 $order->add_item( $shipping );
182 $order->calculate_totals();
183 $order->set_shipping_tax( $order_data['shipping_charges']['tax_total_fcy'] ?? 0 );
184 $order->set_customer_note( $order_data['notes'] );
185 $order->save();
186 $order->update_meta_data( 'zi_salesorder_id', $order_data['salesorder_id'] );
187 $order->save();
188 $response->set_data(
189 array(
190 'id' => $order->get_id(),
191 'items' => array_map(
192 function ($item) {
193 return array(
194 'product_id' => $item->get_product_id(),
195 'quantity' => $item->get_quantity(),
196 'price' => $item->get_total(),
197 );
198 },
199 $order->get_items()
200 ),
201 'total' => $order->get_total(),
202 )
203 );
204 }
205
206 return $response;
207 }
208
209
210 private function map_status( $status ): string {
211 switch ( $status ) {
212 case 'paid':
213 return 'wc-completed';
214 default:
215 return 'wc-pending';
216 }
217 }
218
219
220 private function get_items( $line_items ): array {
221 $meta_ids = array_column( $line_items, 'sku' );
222 $product_ids = array();
223 foreach ( $line_items as $item ) {
224 $product_id = wc_get_product_id_by_sku( $item['sku'] );
225 if ( $product_id ) {
226 $product_ids[] = $product_id;
227 }
228 }
229 if ( count( $product_ids ) !== count( $meta_ids ) ) {
230 return array( 'not_found' => array_diff( $meta_ids, array_keys( $product_ids ) ) );
231 }
232
233 return $product_ids;
234 }
235
236 private function get_order_id( $zi_id ): int {
237 // Define your meta query arguments
238 $args = array(
239 'meta_query' => array(
240 array(
241 'key' => 'zi_salesorder_id',
242 'value' => $zi_id,
243 'compare' => '=',
244 ),
245 ),
246 );
247
248 // Get orders based on meta query
249 $orders = wc_get_orders( $args );
250 if ( count( $orders ) > 0 ) {
251 return $orders[0]->get_id();
252 }
253 return 0;
254 }
255 }
256