PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.2.17
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.2.17
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 / purchase-orders / class-cmbird-purchase-order.php
commercebird / includes / classes / purchase-orders Last commit date
class-cmbird-purchase-admin.php 1 year ago class-cmbird-purchase-order.php 1 year ago class-cmbird-rest-shop-purchase-controller.php 1 year ago index.php 1 year ago
class-cmbird-purchase-order.php
356 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 // Ensure WooCommerce is active
8 if ( ! class_exists( 'WC_Order' ) ) {
9 return;
10 }
11
12 /**
13 * Purchase Order Class
14 *
15 * This class extends the WC_Order class to add custom functionality for purchase orders.
16 */
17
18 class CMBIRD_Purchase_Order extends WC_Order {
19 public $order_type = 'shop_purchase';
20
21 public function __construct( $order_id = 0 ) {
22 parent::__construct( $order_id );
23 $this->order_type = 'shop_purchase';
24 // Custom initialization code for purchase orders can go here
25 }
26
27 public function get_type() {
28 return 'shop_purchase';
29 }
30
31 // You can override or add methods for handling purchase orders
32 public function is_purchase() {
33 return true;
34 }
35
36 public function remove_item( $item_id ) {
37 parent::remove_item( $item_id );
38 parent::calculate_totals();
39 }
40
41 // update meta data
42 public function update_meta_data( $key, $value, $meta_id = 0 ) {
43 parent::update_meta_data( $key, $value, $meta_id );
44 // Custom logic for updating meta data for purchase orders
45 }
46 }
47
48 // Register the custom order type
49 function cmbird_register_shop_purchase_order_type() {
50 wc_register_order_type( 'shop_purchase', array(
51 'labels' => array(
52 'name' => __( 'Purchase Orders', 'commercebird' ),
53 'singular_name' => __( 'Purchase Order', 'commercebird' ),
54 'add_new' => _x( 'Add Purchase', 'custom post type setting', 'commercebird' ),
55 'add_new_item' => _x( 'Add New Purchase', 'custom post type setting', 'commercebird' ),
56 'edit' => _x( 'Edit', 'custom post type setting', 'commercebird' ),
57 'edit_item' => _x( 'Edit Purchase', 'custom post type setting', 'commercebird' ),
58 'new_item' => _x( 'New Purchase', 'custom post type setting', 'commercebird' ),
59 'view' => _x( 'View Purchase', 'custom post type setting', 'commercebird' ),
60 'view_item' => _x( 'View Purchase', 'custom post type setting', 'commercebird' ),
61 'search_items' => __( 'Search Purchases', 'commercebird' ),
62 'not_found_in_trash' => _x( 'No Purchases found in trash', 'custom post type setting', 'commercebird' ),
63 'parent' => _x( 'Parent Purchases', 'custom post type setting', 'commercebird' ),
64 'menu_name' => __( 'Purchases', 'commercebird' ),
65 ),
66 'public' => false,
67 'show_ui' => true,
68 'capability_type' => 'shop_order',
69 'map_meta_cap' => true,
70 'exclude_from_search' => true,
71 'publicly_queryable' => false,
72 'show_in_menu' => current_user_can( 'manage_woocommerce' ) ? 'woocommerce' : true,
73 'hierarchical' => false,
74 'has_archive' => false,
75 'exclude_from_orders_screen' => true,
76 'exclude_from_order_webhooks' => true,
77 'exclude_from_order_count' => true,
78 'exclude_from_order_views' => true,
79 'exclude_from_order_reports' => true,
80 'exclude_from_order_sales_reports' => true,
81 'add_order_meta_boxes' => true,
82 'class_name' => 'CMBIRD_Purchase_Order',
83 ) );
84
85 register_post_status(
86 'wc-awaiting-approval',
87 array(
88 'label' => _x( 'Awaiting Approval', 'Order status', 'commercebird' ),
89 'public' => true,
90 'exclude_from_search' => false,
91 'show_in_admin_all_list' => true,
92 'show_in_admin_status_list' => true,
93 // translators: 1-2: 1: count
94 'label_count' => _n_noop( 'Awaiting Approval <span class="count">(%s)</span>', 'Awaiting Approval <span class="count">(%s)</span>', 'commercebird' ),
95 )
96 );
97
98 register_post_status(
99 'wc-approved',
100 array(
101 'label' => _x( 'Approved', 'Order status', 'commercebird' ),
102 'public' => true,
103 'exclude_from_search' => false,
104 'show_in_admin_all_list' => true,
105 'show_in_admin_status_list' => true,
106 // translators: 1-2: 1: count
107 'label_count' => _n_noop( 'Approved <span class="count">(%s)</span>', 'Approved <span class="count">(%s)</span>', 'commercebird' ),
108 )
109 );
110
111 register_post_status(
112 'wc-received',
113 array(
114 'label' => _x( 'Received', 'Order status', 'commercebird' ),
115 'public' => true,
116 'exclude_from_search' => false,
117 'show_in_admin_all_list' => true,
118 'show_in_admin_status_list' => true,
119 // translators: 1-2: 1: count
120 'label_count' => _n_noop( 'Received <span class="count">(%s)</span>', 'Received <span class="count">(%s)</span>', 'commercebird' ),
121 )
122 );
123
124 // Create the "vendor" role
125 add_role(
126 'vendor',
127 __( 'Vendor', 'commercebird' ),
128 array(
129 'read' => true,
130 )
131 );
132
133 }
134 add_action( 'init', 'cmbird_register_shop_purchase_order_type' );
135
136 // Load custom class for Purchase Orders
137 function cmbird_load_purchase_order_class( $order_classname, $order_type, $order_id ) {
138 if ( 'shop_purchase' === $order_type ) {
139 $order_classname = 'CMBIRD_Purchase_Order';
140 }
141 return $order_classname;
142 }
143 add_filter( 'woocommerce_order_class', 'cmbird_load_purchase_order_class', 10, 3 );
144
145 /**
146 * Custom order statuses for Purchase Orders
147 * @param mixed $order_statuses
148 * @return array
149 * @since 1.0.0
150 */
151 // Add custom order statuses for 'shop_purchase'
152 function cmbird_custom_order_statuses( $order_statuses ) {
153
154 // check if current screen is shop_purchase with wc_get_screen_id()
155 if ( ! wc_get_order_type( 'shop_purchase' ) ) {
156 return $order_statuses;
157 }
158
159 $new_order_statuses = array();
160 foreach ( $order_statuses as $key => $status ) {
161 $new_order_statuses[ $key ] = $status;
162 if ( 'wc-pending' === $key ) {
163 $new_order_statuses['wc-awaiting-approval'] = 'Awaiting Approval';
164 $new_order_statuses['wc-approved'] = 'Approved';
165 $new_order_statuses['wc-received'] = 'Received';
166 }
167 }
168 return $new_order_statuses;
169 }
170 add_filter( 'wc_order_statuses', 'cmbird_custom_order_statuses' );
171
172 function cmbird_custom_shop_purchase_bulk_actions( $bulk_actions ) {
173 $bulk_actions['mark_awaiting_approval'] = __( 'Change status to awaiting approval', 'commercebird' );
174 $bulk_actions['mark_approved'] = __( 'Change status to approved', 'commercebird' );
175 $bulk_actions['mark_received'] = __( 'Change status to received', 'commercebird' );
176
177 // unset the statuses that are not needed - e.g. 'mark_processing'
178 unset( $bulk_actions['mark_processing'] );
179 unset( $bulk_actions['mark_on-hold'] );
180 unset( $bulk_actions['mark_completed'] );
181
182 return $bulk_actions;
183 }
184 add_filter( 'bulk_actions-edit-shop_purchase', 'cmbird_custom_shop_purchase_bulk_actions' );
185 // HPOS Screens
186 add_filter( 'bulk_actions-woocommerce_page_wc-orders--shop_purchase', 'cmbird_custom_shop_purchase_bulk_actions' );
187
188
189 function cmbird_handle_custom_status_transitions( $order_id, $old_status, $new_status ) {
190
191 if ( 'awaiting-approval' === $new_status ) {
192 // Logic for when the order is awaiting approval
193 }
194
195 if ( 'approved' === $new_status ) {
196 // Logic for when the order is approved
197 }
198
199 if ( 'received' === $new_status ) {
200 // Increase the stock of the products in the order when the order is received
201 $order = wc_get_order( $order_id );
202 foreach ( $order->get_items() as $item_id => $item ) {
203 $product = $item->get_product();
204 if ( $product && $product->managing_stock() ) { // Check if stock management is enabled
205 $stock_quantity = $product->get_stock_quantity();
206 $new_stock = $stock_quantity + $item->get_quantity();
207
208 // Update stock quantity
209 $product->set_stock_quantity( $new_stock );
210 $product->save();
211 }
212 }
213 }
214 }
215 add_action( 'woocommerce_order_status_changed', 'cmbird_handle_custom_status_transitions', 10, 3 );
216
217 // Set cost price in purchase orders when created or edited via Admin
218 function cmbird_set_cost_price_for_admin_purchase_order( $post_id, $post, $update ) {
219 if ( 'shop_purchase' === wc_get_order_type( $post_id ) ) {
220
221 $order = wc_get_order( $post_id );
222
223 if ( $order && 'shop_purchase' === $order->get_type() ) {
224
225 foreach ( $order->get_items() as $item_id => $item ) {
226 $product = $item->get_product();
227
228 if ( $product ) {
229 // Get the cost price from product meta
230 $cost_price = get_post_meta( $product->get_id(), '_cost_price', true );
231
232 // If cost price is set, update the item price in the order
233 if ( $cost_price && is_numeric( $cost_price ) ) {
234 $item->set_subtotal( $cost_price * $item->get_quantity() );
235 $item->set_total( $cost_price * $item->get_quantity() );
236 $item->save();
237 }
238 }
239 }
240
241 // Recalculate totals for the order after setting cost price
242 $order->calculate_totals();
243
244 // Set the store's address as the shipping address for purchase orders
245 $warehouse_address = get_option( 'woocommerce_wh_address', '' );
246 $warehouse_address_2 = get_option( 'woocommerce_wh_address_2', '' );
247 $warehouse_city = get_option( 'woocommerce_wh_city', '' );
248 $warehouse_state = get_option( 'woocommerce_wh_state', '' );
249 $warehouse_country = get_option( 'woocommerce_wh_country', '' );
250 $warehouse_zip = get_option( 'woocommerce_wh_postcode', '' );
251
252 // Update the shipping address with store details
253 $shipping_address = array(
254 'first_name' => 'Store',
255 'last_name' => 'Address',
256 'company' => get_option( 'blogname' ),
257 'address_1' => $warehouse_address,
258 'address_2' => $warehouse_address_2,
259 'city' => $warehouse_city,
260 'state' => $warehouse_state,
261 'postcode' => $warehouse_zip,
262 'country' => $warehouse_country,
263 );
264
265 // Set the new shipping address for the order
266 $order->set_address( $shipping_address, 'shipping' );
267
268 // save shipping address as customer shipping address.
269 $customer = $order->get_customer();
270 $customer->set_shipping_address( $shipping_address );
271 $customer->save();
272 }
273 }
274 }
275 add_action( 'save_post_shop_purchase', 'cmbird_set_cost_price_for_admin_purchase_order', 10, 3 );
276
277 // Add warehouse address in woocommerce settings
278 add_filter( 'woocommerce_general_settings', 'cmbird_additional_store_addresses_admin', 9999 );
279
280 function cmbird_additional_store_addresses_admin( $settings ) {
281
282 $new_settings = array(
283
284 array(
285 'title' => 'Warehouse Address',
286 'type' => 'title',
287 'id' => 'wh_address',
288 ),
289
290 array(
291 'title' => __( 'Address line 1', 'commercebird' ),
292 'id' => 'woocommerce_wh_address',
293 'type' => 'text',
294 ),
295
296 array(
297 'title' => __( 'Address line 2', 'commercebird' ),
298 'id' => 'woocommerce_wh_address_2',
299 'type' => 'text',
300 ),
301
302 array(
303 'title' => __( 'City', 'commercebird' ),
304 'id' => 'woocommerce_wh_city',
305 'type' => 'text',
306 ),
307
308 array(
309 'title' => __( 'State', 'commercebird' ),
310 'id' => 'woocommerce_wh_state',
311 'type' => 'text',
312 ),
313
314 array(
315 'title' => __( 'Country', 'commercebird' ),
316 'id' => 'woocommerce_wh_country',
317 'type' => 'single_select_country',
318 ),
319
320 array(
321 'title' => __( 'Postcode / ZIP', 'commercebird' ),
322 'id' => 'woocommerce_wh_postcode',
323 'type' => 'text',
324 ),
325
326 array(
327 'type' => 'sectionend',
328 'id' => 'wh_address',
329 ),
330
331 );
332
333 return array_merge( array_slice( $settings, 0, 7 ), $new_settings, array_slice( $settings, 7 ) );
334 }
335
336 /**
337 * Use 'woocommerce_rest_insert_customer' action hook to change the user role to vendor when creating customer.
338 *
339 * @param WP_User $user_data Data used to create the customer.
340 * @param WP_REST_Request $request Request object.
341 * @param boolean $creating True when creating customer, false when updating customer.
342 */
343 function cmbird_change_user_role_to_vendor( $user_data, $request, $creating ) {
344 // Get the property 'role' from the request object
345 $role = $request->get_param( 'role' );
346
347 // Change the user role to 'vendor'
348 if ( ! empty( $role ) && 'vendor' === $role ) {
349 $user_data->set_role( 'vendor' );
350 }
351
352 // Return the user data
353 return $user_data;
354 }
355 add_action( 'woocommerce_rest_insert_customer', 'cmbird_change_user_role_to_vendor', 10, 3 );
356