PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.3.9
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.3.9
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-import-price-list.php
commercebird / includes / classes / zoho-inventory Last commit date
class-categories.php 1 year ago class-import-image.php 1 year ago class-import-items.php 1 year ago class-import-price-list.php 1 year ago class-multi-currency.php 1 year ago class-order-sync.php 1 year ago class-product.php 1 year ago class-users-contact.php 1 year ago index.php 1 year ago
class-import-price-list.php
339 lines
1 <?php
2 /**
3 * Class to import Pricelists from Zoho to WooCommerce using B2B for WooCommerce
4 *
5 * @package WooZo Inventory
6 */
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit;
9 }
10
11 class CMBIRD_Pricelist_ZI {
12 use CommerceBird\Admin\Traits\LogWriter;
13
14 private array $config;
15
16 public function __construct() {
17 $this->config = array(
18 'ProductZI' => array(
19 'OID' => get_option( 'cmbird_zoho_inventory_oid' ),
20 'APIURL' => get_option( 'cmbird_zoho_inventory_url' ),
21 ),
22 );
23 }
24
25 /**
26 * Get all Zoho price list
27 * Example response:
28 * {
29 * "currency_code": Code based on currency,
30 * "currency_id": The currenct id of the currency,
31 * "decimal_place": Decimal place for pricebook.,
32 * "description": Description about the pricebook,
33 * "is_default": To check the default pricebook.Allowed values: true,false,
34 * "is_increase": Mark up or Mark down to discounts.Allowed values: true,false,
35 * "name": Name of the pricebook,
36 * "percentage": About percentage of discounts,
37 * "pricebook_id": Unique ID generated by server for the price book,
38 * "pricebook_items": [
39 * {
40 * "item_id": Unique ID generated by server for Item,
41 * "pricebook_rate": Rate of the price book for the Items,
42 * "pricebook_item_id": Unique ID generated by the server for each pricebook line item
43 * }
44 * ],
45 * "pricebook_type": Type of the pricebook.Allowed values: per_item,fixed_percentage,
46 * "rounding_type": Type of the rounding.Allowed values: no_rounding,round_to_dollor,round_to_dollar_minus_01,round_to_half_dollar,round_to_half_dollar_minus_01,
47 * "sales_or_purchase_type": Whether its sales or purchase type.Allowed values: sales,purchases,
48 * "status": Status of the price book
49 *}
50 * @return array of price list
51 */
52 public function zi_get_all_pricelist(): array {
53 $in_cache = get_transient( 'zoho_pricelist' );
54 if ( $in_cache ) {
55 return $in_cache;
56 }
57
58 $url = $this->config['ProductZI']['APIURL'] . 'inventory/v1/pricebooks?organization_id=' . $this->config['ProductZI']['OID'];
59 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
60 $json = $execute_curl_call_handle->execute_curl_call_get( $url );
61
62 if ( isset( $json->pricebooks ) ) {
63 set_transient( 'zoho_pricelist', $json->pricebooks, MINUTE_IN_SECONDS );
64
65 return $json->pricebooks;
66 }
67
68 return array();
69 }
70
71 /**
72 * Save pricelist function to update prices and discounts for user roles.
73 *
74 * @param array $post The post-data containing user role and price information.
75 * Example:
76 * {
77 * "zoho_inventory_pricelist": Zoho inventory pricelist id
78 * "wp_user_role": WordPress user role
79 * }
80 */
81 public function save_price_list( array $post ): bool {
82 if ( class_exists( 'Addify_B2B_Plugin' ) ) {
83 $success = $this->addify_b2b( $post['zoho_inventory_pricelist'], $post['wp_user_role'] );
84 } elseif ( class_exists( 'WooCommerceB2B' ) ) {
85 $success = $this->wc_b2b( $post['wcb2b'] );
86 }
87 return $success;
88 }
89
90 /**
91 * Get a Zoho price list based on a price book id
92 *
93 * @param int $pricebook_id
94 *
95 * @return array of price list
96 */
97 private function get_zoho_pricebook( int $pricebook_id ): array {
98 $in_cache = get_transient( 'zoho_pricelist_' . $pricebook_id );
99 if ( $in_cache ) {
100 return $in_cache;
101 }
102 $url = $this->config['ProductZI']['APIURL'] . 'inventory/v1/pricebooks/' . $pricebook_id . '?organization_id=' . $this->config['ProductZI']['OID'];
103 $execute_curl_call_handle = new CMBIRD_API_Handler_Zoho();
104 $json = $execute_curl_call_handle->execute_curl_call_get( $url );
105 if ( is_object( $json ) && property_exists( $json, 'pricebook' ) ) {
106 $json = json_decode( wp_json_encode( $json->pricebook ), true );
107 set_transient( 'zoho_pricelist_' . $pricebook_id, $json, DAY_IN_SECONDS );
108 update_option( 'cmbird_zoho_pricelist_id', $pricebook_id );
109
110 return $json;
111 }
112
113 return array();
114 }
115
116 /**
117 * Get published product ids, based on zi_item_id meta-key
118 *
119 * @return array
120 */
121 private function get_zoho_products(): array {
122 $in_cache = get_transient( 'zoho_products' );
123 if ( $in_cache ) {
124 return $in_cache;
125 }
126 global $wpdb;
127
128 $ids = $wpdb->get_results(
129 "SELECT p.ID AS id, pm.meta_value AS zi_item_id
130 FROM {$wpdb->postmeta} pm
131 INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID
132 WHERE pm.meta_key = 'zi_item_id'
133 AND p.post_type in ('product', 'product_variation')
134 AND p.post_status = 'publish'
135 AND pm.meta_value != ''",
136 ARRAY_A
137 );
138
139 $plist = wp_list_pluck( $ids, 'id', 'zi_item_id' );
140 ksort( $plist );
141 set_transient( 'zoho_products', $plist, DAY_IN_SECONDS );
142
143 return $plist;
144 }
145
146 /**
147 * Support For Addify B2B
148 *
149 * @param int $pricebook_id pricebook id
150 * @param string $role user role
151 */
152 private function addify_b2b( int $pricebook_id, string $role ): bool {
153 $price_book = $this->get_zoho_pricebook( $pricebook_id );
154 $zi_item_ids = $this->get_zoho_products();
155
156 if ( empty( $price_book ) ) {
157 return false;
158 }
159
160 $meta_collection = array();
161 if ( isset( $price_book['pricebook_type'] ) && $price_book['pricebook_type'] === 'fixed_percentage' ) {
162 $meta_collection['price'] = $price_book['percentage'] ?? 0;
163 $meta_collection['ids'] = array_fill_keys( array_values( $zi_item_ids ), $meta_collection['price'] );
164 $meta_collection['orderby'] = $price_book['is_increase'] ? 'percentage_increase' : 'percentage_decrease';
165 } else {
166 $meta_collection['orderby'] = 'fixed_price';
167 foreach ( $price_book['pricebook_items'] as $itemlist ) {
168 if ( isset( $zi_item_ids[ $itemlist['item_id'] ] ) ) {
169 $meta_collection['ids'][ $zi_item_ids[ $itemlist['item_id'] ] ] = array();
170 if ( is_array( $itemlist['price_brackets'] ) && ! empty( $itemlist['price_brackets'] ) ) {
171 $priceBracket = $itemlist['price_brackets'][0];
172 $meta_collection['ids'][ $zi_item_ids[ $itemlist['item_id'] ] ] = array(
173 'start_quantity' => $priceBracket['start_quantity'] ?? 0,
174 'end_quantity' => $priceBracket['end_quantity'] ?? 0,
175 'pricebook_rate' => $priceBracket['pricebook_rate'] ?? 0,
176 );
177 } else {
178 $meta_collection['ids'][ $zi_item_ids[ $itemlist['item_id'] ] ] = $itemlist['pricebook_rate'] ?? 0;
179 }
180 }
181 }
182 }
183
184 if ( empty( $meta_collection['ids'] ) ) {
185 return false;
186 }
187
188 foreach ( $meta_collection['ids'] as $product_id => $price ) {
189 $formatted_price = str_replace( '.', wc_get_price_decimal_separator(), $meta_collection['price'] ?? $price );
190 $metavalue = array(
191 'discount_type' => $meta_collection['orderby'],
192 'user_role' => $role,
193 'discount_value' => is_array( $formatted_price ) ? $formatted_price['pricebook_rate'] : $formatted_price,
194 'min_qty' => is_array( $formatted_price ) ? $formatted_price['start_quantity'] : '',
195 'max_qty' => is_array( $formatted_price ) ? $formatted_price['end_quantity'] : '',
196 );
197 $postmeta_array = get_post_meta( $product_id, '_role_base_price', true );
198 $updated = false;
199
200 if ( is_array( $postmeta_array ) && ! empty( $postmeta_array ) ) {
201 foreach ( $postmeta_array as &$postmeta ) {
202 if ( $postmeta['user_role'] === $role ) {
203 $postmeta = $metavalue;
204 $updated = true;
205 break;
206 }
207 }
208 if ( ! $updated ) {
209 $postmeta_array[] = $metavalue;
210 }
211 }
212
213 update_post_meta( $product_id, '_role_base_price', $postmeta_array );
214 }
215 return true;
216 }
217
218
219
220 private function wc_b2b( $group_settings ): bool {
221 $group_settings = json_decode( $group_settings, true );
222 if ( empty( $group_settings ) ) {
223 return false;
224 }
225 foreach ( $group_settings as $group_setting ) {
226 $group_id = $group_setting['key'];
227 $pricebook_id = $group_setting['value'];
228 delete_transient( 'wcb2b_synced_groups' );
229 $price_book = $this->get_zoho_pricebook( $pricebook_id );
230 if ( empty( $price_book ) ) {
231 continue;
232 }
233 $zi_item_ids = $this->get_zoho_products();
234 switch ( $price_book['pricebook_type'] ) {
235 case 'fixed_percentage':
236 update_post_meta( $group_id, 'wcb2b_group_discount', $price_book['percentage'] );
237 update_post_meta( $group_id, 'pricebook_id', $pricebook_id );
238 update_post_meta( $group_id, 'pricebook_name', $price_book['name'] );
239 break;
240 case 'per_item':
241 foreach ( $price_book['pricebook_items'] as $pricebook_item ) {
242 if ( ! isset( $zi_item_ids[ $pricebook_item['item_id'] ] ) ) {
243 continue;
244 }
245 $product_id = $zi_item_ids[ $pricebook_item['item_id'] ];
246 $product_group_prices = $product_group_min = $product_group_max = array();
247 if ( is_array( $pricebook_item['price_brackets'] ) && count( $pricebook_item['price_brackets'] ) > 0 ) {
248 $price = $pricebook_item['price_brackets'][0]['pricebook_rate'];
249 $product_group_prices[ $group_id ]['regular_price'] = $price;
250 $product_group_min[ $group_id ] = $pricebook_item['price_brackets'][0]['start_quantity'];
251 $product_group_max[ $group_id ] = $pricebook_item['price_brackets'][0]['end_quantity'];
252 } else {
253 $product_group_prices[ $group_id ]['regular_price'] = $pricebook_item['pricebook_rate'];
254 }
255 update_post_meta( $group_id, 'pricebook_id', $pricebook_id );
256 update_post_meta( $group_id, 'pricebook_name', $price_book['name'] );
257 if ( ! empty( $product_group_prices ) ) {
258 update_post_meta( $product_id, 'wcb2b_product_group_prices', $product_group_prices );
259 }
260 if ( ! empty( $product_group_min ) ) {
261 update_post_meta( $product_id, 'wcb2b_product_group_min', $product_group_min );
262 }
263 if ( ! empty( $product_group_max ) ) {
264 update_post_meta( $product_id, 'wcb2b_product_group_max', $product_group_max );
265 }
266 }
267 break;
268 default:
269 break;
270 }
271 }
272
273 return true;
274 }
275
276 public function wc_b2b_groups() {
277 $in_cache = get_transient( 'wc_b2b_groups' );
278 if ( ! empty( $in_cache ) ) {
279 return $in_cache;
280 }
281 global $wpdb;
282
283 $results = $wpdb->get_results(
284 "SELECT ID AS id, post_title AS label
285 FROM {$wpdb->posts} p
286 WHERE p.post_type = 'wcb2b_group'
287 AND p.post_status = 'publish'",
288 ARRAY_A // Return results as an associative array
289 );
290
291 if ( empty( $results ) ) {
292 return array();
293 }
294 $groups = wp_list_pluck( $results, 'label', 'id' );
295 set_transient( 'wc_b2b_groups', $groups, DAY_IN_SECONDS );
296
297 return $groups;
298 }
299
300 /**
301 * Retrieves and caches the B2B groups from the database.
302 *
303 * @return array The B2B groups data.
304 */
305 private function wc_b2b_groups_by_rule() {
306 $in_cache = get_transient( 'wc_b2b_groups' );
307 if ( ! empty( $in_cache ) ) {
308 return $in_cache;
309 }
310 global $wpdb;
311
312 $results = $wpdb->get_results(
313 "SELECT p . ID as id, pm . meta_value as rule
314 FROM {$wpdb->posts} p
315 INNER JOIN {$wpdb->postmeta} pm ON p . ID = pm . post_id
316 WHERE p . post_type = 'wcb2b_group'
317 and pm . meta_key = 'wcb2b_group_price_rule'",
318 ARRAY_A // Return results as an associative array
319 );
320
321 if ( empty( $results ) ) {
322 return array();
323 }
324 $grouped_data = array_reduce(
325 $results,
326 function ($result, $item) {
327 $result[ $item['rule'] ][] = $item['id'];
328
329 return $result;
330 },
331 array()
332 );
333
334 set_transient( 'wc_b2b_groups', $grouped_data, DAY_IN_SECONDS );
335
336 return $grouped_data;
337 }
338 }
339