PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.7.7
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.7.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 / apis / class-api-for-exact-webhooks.php
commercebird / includes / classes / apis Last commit date
class-api-for-cmbird.php 7 months ago class-api-for-exact-webhooks.php 4 months ago class-api-for-product-webhook.php 4 months ago class-api-for-shipping-status.php 9 months ago class-api-for-woo-order.php 4 months ago class-api-for-zoho-inventory.php 9 months ago class-commercebird-list-items-api-controller.php 10 months ago class-commercebird-media-api-controller.php 10 months ago class-commercebird-metadata-controller.php 5 months ago index.php 1 year ago trait-api-permission.php 7 months ago
class-api-for-exact-webhooks.php
187 lines
1 <?php
2
3 namespace CommerceBird\API;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 use WP_REST_Response;
10 use WP_REST_Server;
11 use WP_REST_Controller;
12 use WP_REST_Request;
13 use ReflectionClass;
14 use WP_Query;
15 use WC_Product;
16
17 class Exact extends WP_REST_Controller {
18
19 protected $prefix = 'wc/v3';
20 protected $rest_base = 'exact-webhooks';
21
22 public function __construct() {
23
24 register_rest_route(
25 $this->prefix,
26 '/' . $this->rest_base . '/process/',
27 array(
28 'methods' => WP_REST_Server::CREATABLE,
29 'callback' => array( $this, 'process_webhook' ),
30 'permission_callback' => function () {
31 return current_user_can( 'manage_woocommerce' );
32 },
33 )
34 );
35 }
36
37 public function process_webhook( WP_REST_Request $request ) {
38 // $fd = fopen( __DIR__ . '/debug_exact_webhook.txt', 'w+' );
39 // Access the protected body property using reflection.
40 $reflection = new ReflectionClass( $request );
41 $property = $reflection->getProperty( 'body' );
42 // $property->setAccessible( true );
43 $body = $property->getValue( $request );
44 // Decode the JSON body.
45 $data = json_decode( $body, true );
46 // fwrite( $fd, print_r( $data, true ) . "\n" );
47 // fclose( $fd );
48
49 if ( empty( $data ) ) {
50 return new WP_REST_Response( 'Invalid JSON data', 400 );
51 }
52
53 // use php switch case to handle different webhook types. e.g. Invoice, Item and StockPositions.
54 // code starts here.
55 switch ( $data['type'] ) {
56 case 'Items':
57 // process Item webhook. Find the product based on the $data['Code'] which is the sku or post_id.
58 $product_id = wc_get_product_id_by_sku( $data['Code'] );
59 if ( ! $product_id ) {
60 $product_id = $data['Code'];
61 }
62 // Check if category exists with $item['ItemGroupDescription'], else create it and get the ID.
63 if ( isset( $data['ItemGroupDescription'] ) ) {
64 $term = get_term_by( 'name', $data['ItemGroupDescription'], 'product_cat' );
65 $term_id = $term->term_id;
66 if ( empty( $term_id ) ) {
67 $term = wp_insert_term(
68 $data['ItemGroupDescription'],
69 'product_cat',
70 array(
71 'parent' => 0,
72 )
73 );
74 $term_id = $term['term_id'];
75 }
76 } else {
77 $term_id = 0;
78 }
79 $product = wc_get_product( $product_id );
80 if ( $product ) {
81 $product->set_name( $data['Description'] );
82 $product->set_stock_quantity( $data['Stock'] );
83 // update the product price if needed.
84 $product->set_price( $data['StandardSalesPrice'] );
85 $product->set_regular_price( $data['StandardSalesPrice'] );
86 if ( $data['Stock'] > 0 ) {
87 $product->set_manage_stock( true );
88 $product->set_stock_quantity( $data['Stock'] );
89 $product->set_stock_status( 'instock' );
90 }
91 // add meta data cost_price.
92 $product->update_meta_data( '_cogs_total_value', $data['CostPriceStandard'] );
93 // set the category.
94 $product->set_category_ids( array_map( 'intval', array( $term_id ) ) );
95 $product->save();
96 } else {
97 // if product not found, create a new product if the $data['Webshop'] is set to true.
98 if ( ! $data['IsWebshopItem'] ) {
99 break;
100 }
101 $product = new WC_Product();
102 $product->set_name( $data['Description'] );
103 $product->set_sku( $data['Code'] );
104 $product->set_price( $data['StandardSalesPrice'] );
105 $product->set_regular_price( $data['StandardSalesPrice'] );
106 if ( $data['Stock'] > 0 ) {
107 $product->set_manage_stock( true );
108 $product->set_stock_quantity( $data['Stock'] );
109 $product->set_stock_status( 'instock' );
110 }
111 // set the category.
112 $product->set_category_ids( array_map( 'intval', array( $term_id ) ) );
113 $product->set_status( 'draft' );
114 $product->set_category_ids( array_map( 'intval', array( $term_id ) ) );
115 $product->save();
116 }
117 break;
118 case 'StockPositions':
119 // process StockPositions webhook.
120 // get the "ItemId" from $data['ItemId'] and find the product based on product meta key "eo_item_id".
121 $item_id = $data['ItemId'];
122 // find the product id based on meta key "eo_item_id" which has the value of $item_id using WP query.
123 $args = array(
124 'post_type' => 'product',
125 'meta_query' => array(
126 array(
127 'key' => 'eo_item_id',
128 'value' => $item_id,
129 ),
130 ),
131 );
132 $query = new WP_Query( $args );
133 if ( $query->have_posts() ) {
134 while ( $query->have_posts() ) {
135 $query->the_post();
136 $product_id = get_the_ID();
137 $product = wc_get_product( $product_id );
138 // Check if its a variation product.
139 if ( $product && $product->is_type( 'variation' ) ) {
140 // get variation instance.
141 $variation = wc_get_product_object( 'variation', $product_id );
142 $variation->set_props(
143 array(
144 'stock_quantity' => intval( $data['FreeStock'] ),
145 'manage_stock' => true,
146 )
147 );
148 // get stock quantity of variation, if its higher than 0, set stock status to instock.
149 if ( $variation->get_stock_quantity() > 0 ) {
150 $variation->set_stock_status( 'instock' );
151 } else {
152 $stock_status = $variation->backorders_allowed() ? 'onbackorder' : 'outofstock';
153 $variation->set_stock_status( $stock_status );
154 }
155 $variation->save();
156 // Clear cache.
157 wc_delete_product_transients( $product_id );
158 } else {
159 $product->set_manage_stock( true );
160 $product->set_stock_quantity( intval( $data['FreeStock'] ) );
161 $product->save();
162 // get new product instance.
163 $product = wc_get_product( $product_id );
164 // get stock quantity of product, if its higher than 0, set stock status to instock.
165 if ( $product->get_stock_quantity() > 0 ) {
166 $product->set_stock_status( 'instock' );
167 } else {
168 $stock_status = $product->backorders_allowed() ? 'onbackorder' : 'outofstock';
169 $product->set_stock_status( $stock_status );
170 }
171 $product->save();
172 // Clear cache.
173 wc_delete_product_transients( $product_id );
174 }
175 }
176 wp_reset_postdata();
177 }
178 break;
179 default:
180 // process default webhook.
181 break;
182 }
183 // code ends here.
184 return new WP_REST_Response( 'Webhook processed', 200 );
185 }
186 }
187