WooCommerce: ที่ตั้งสินค้าคงคลังเพิ่มเติม

เผยแพร่แล้ว: 2022-12-07

ปลั๊กอิน WooCommerce ช่วยให้คุณจัดการสต็อกสำหรับแต่ละผลิตภัณฑ์ แต่คุณมีช่องปริมาณสต็อกเพียงช่องเดียว!

จะเป็นอย่างไรหากคุณมีคลังสินค้า 2 แห่ง และในฐานะผู้ดูแลร้านค้า จำเป็นต้องจัดการสินค้าคงคลังสำหรับสถานที่แต่ละแห่ง ? นอกจากนี้ จะเกิดอะไรขึ้นหากสินค้าหมดสต็อกที่ตำแหน่งที่ 1 แต่มีอยู่ในสต็อกที่ตำแหน่งที่ 2 ดังนั้นลูกค้าจึงจำเป็นต้องซื้อได้

วิธีแก้ปัญหาที่น่าทึ่งนี้จะเพิ่มหมายเลขอินพุตที่สองในการตั้งค่าผลิตภัณฑ์ กำหนดปริมาณและสถานะของสต็อกใหม่ในส่วนหน้าโดยการสรุปสต็อก 1 + สต็อก 2 และสุดท้ายลดสต็อก 1 ลงจนเหลือ 0 หลังจากนั้นจะลดสต็อก 2

พฤติกรรมเริ่มต้นนี้สามารถเปลี่ยนแปลงได้แน่นอน เช่น สามารถกำหนดจากจุดที่สต็อกลดลง (ตามระยะทาง?) ผ่านรหัสเพิ่มเติม นอกจากนี้ ยังสามารถเขียนโค้ดเพิ่มเติมเพื่อให้เข้ากันได้กับผลิตภัณฑ์ผันแปรหรือประเภทผลิตภัณฑ์ที่กำหนดเอง รวมทั้งทำให้ทำงานร่วมกับการคืนเงินได้ ยังไงก็สนุก!

นี่คือช่องสต็อกที่สอง ในกรณีนี้ ปริมาณสินค้าคงคลังเป็น 0 ในคลังสินค้าเริ่มต้น ดังนั้นในทางเทคนิคแล้ว สินค้าหมดสต็อก จากข้อมูลโค้ดด้านล่าง และข้อเท็จจริงที่ว่ามีสินค้า 1 รายการในสต็อกในตำแหน่งที่ 2 แสดงว่าสินค้านั้น "มีในสต็อก" โดยมีจำนวน "1" ตามคำสั่งซื้อ นี่คือปริมาณที่ลดลง

ตัวอย่าง PHP: การจัดการตำแหน่งสต็อคที่สอง

/**
 * @snippet       Second Stock Location @ WooCommerce Edit Product
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 7
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

add_action( 'woocommerce_product_options_stock', 'bbloomer_additional_stock_location' );

function bbloomer_additional_stock_location() {
	global $product_object;
	echo '<div class="show_if_simple show_if_variable">';
	woocommerce_wp_text_input(
		array(
			'id' => '_stock2',
			'value' => get_post_meta( $product_object->get_id(), '_stock2', true ),
			'label' => '2nd Stock Location',
			'data_type' => 'stock',
		)
	);
	echo '</div>';
}

add_action( 'save_post_product', 'bbloomer_save_additional_stock' );
  
function bbloomer_save_additional_stock( $product_id ) {
    global $typenow;
    if ( 'product' === $typenow ) {
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
		if ( isset( $_POST['_stock2'] ) ) {
			update_post_meta( $product_id, '_stock2', $_POST['_stock2'] );
		}
	}
}

add_filter( 'woocommerce_product_get_stock_quantity' , 'bbloomer_get_overall_stock_quantity', 9999, 2 );

function bbloomer_get_overall_stock_quantity( $value, $product ) {
	$value = (int) $value + (int) get_post_meta( $product->get_id(), '_stock2', true );
    return $value;
}

add_filter( 'woocommerce_product_get_stock_status' , 'bbloomer_get_overall_stock_status', 9999, 2 );

function bbloomer_get_overall_stock_status( $status, $product ) {
	if ( ! $product->managing_stock() ) return $status;
	$stock = (int) $product->get_stock_quantity() + (int) get_post_meta( $product->get_id(), '_stock2', true );
	$status = $stock && ( $stock > 0 ) ? 'instock' : 'outofstock';
    return $status;
}

add_filter( 'woocommerce_payment_complete_reduce_order_stock', 'bbloomer_maybe_reduce_second_stock', 9999, 2 );

function bbloomer_maybe_reduce_second_stock( $reduce, $order_id ) {
	$order = wc_get_order( $order_id );
	$atleastastock2change = false;
	foreach ( $order->get_items() as $item ) {	
		if ( ! $item->is_type( 'line_item' ) ) {
			continue;
		}
		$product = $item->get_product();
		$item_stock_reduced = $item->get_meta( '_reduced_stock', true );
		if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) {
			continue;
		}
		$qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item );
		$stock1 = (int) get_post_meta( $product->get_id(), '_stock', true );
		if ( $qty <= $stock1 ) continue;
		$atleastastock2change = true;
	}
	if ( ! $atleastastock2change ) return $reduce;	
	foreach ( $order->get_items() as $item ) {	
		if ( ! $item->is_type( 'line_item' ) ) {
			continue;
		}
		$product = $item->get_product();
		$item_stock_reduced = $item->get_meta( '_reduced_stock', true );
		if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) {
			continue;
		}	
		$item_name = $product->get_formatted_name();
		$qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item );
		$stock1 = (int) get_post_meta( $product->get_id(), '_stock', true );
		$stock2 = (int) get_post_meta( $product->get_id(), '_stock2', true );
		if ( $qty <= $stock1 ) {
			wc_update_product_stock( $product, $qty, 'decrease' );
			$order->add_order_note( sprintf( 'Reduced stock for item "%s"; Stock 1: "%s" to "%s".', $item_name, $stock1, $stock1 - $qty ) );
		} else {		
			$newstock2 = $stock2 - ( $qty - $stock1 );
			wc_update_product_stock( $product, $stock1, 'decrease' );
			update_post_meta( $product->get_id(), '_stock2', $newstock2 );
			$item->add_meta_data( '_reduced_stock', $qty, true );
			$item->save();				
			$order->add_order_note( sprintf( 'Reduced stock for item "%s"; Stock 1: "%s" to "0" and Stock 2: "%s" to "%s".', $item_name, $stock1, $stock2, $newstock2 ) );
		}
	}
	$order->get_data_store()->set_stock_reduced( $order_id, true );
	return false;
}

ในภาษาอังกฤษธรรมดา:

  • bbbloomer_additional_stock_location แสดงฟิลด์ปริมาณสต็อกที่สอง
  • bbbloomer_save_additional_stock บันทึกจำนวนสต็อกที่กำหนดเอง
  • bbbloomer_get_overall_stock_quantity ตั้งค่าสต็อกสินค้าคงคลังเป็นสต็อก 1 + สต็อก 2
  • bbloomer_get_overall_stock_status กำหนดสถานะสต็อกสินค้าตามสต็อก 1 + สต็อก 2
  • bbbloomer_maybe_reduce_second_stock ลดสต็อกจากสต็อก 1 และจากสต็อก 2 ในกรณีที่ปริมาณที่สั่งซื้อมากกว่าสต็อก 1 มิฉะนั้น WooCommerce จะทำการลดสต็อกเริ่มต้น