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 |