Skip to content

Commit

Permalink
add test for pos visibility
Browse files Browse the repository at this point in the history
  • Loading branch information
kilbot committed Nov 29, 2023
1 parent ff6cf12 commit 458019f
Show file tree
Hide file tree
Showing 4 changed files with 460 additions and 129 deletions.
126 changes: 111 additions & 15 deletions includes/API/Product_Variations_Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace WCPOS\WooCommercePOS\API;

\defined('ABSPATH') || die;
\defined( 'ABSPATH' ) || die;

if ( ! class_exists('WC_REST_Product_Variations_Controller') ) {
if ( ! class_exists( 'WC_REST_Product_Variations_Controller' ) ) {
return;
}

Expand All @@ -15,6 +15,8 @@
use WP_Query;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use WC_Product_Variation;

/**
* Product Tgas controller class.
Expand All @@ -41,6 +43,20 @@ public function __construct() {

if ( method_exists( parent::class, '__construct' ) ) {
parent::__construct();

register_rest_route(
$this->namespace,
'/products/variations',
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'wcpos_get_all_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_collection_params(),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}
}

Expand All @@ -49,21 +65,21 @@ public function __construct() {
*/
public function get_item_schema() {
$schema = parent::get_item_schema();

// Add the 'barcode' property if 'properties' exists and is an array
if (isset($schema['properties']) && \is_array($schema['properties'])) {
if ( isset( $schema['properties'] ) && \is_array( $schema['properties'] ) ) {
$schema['properties']['barcode'] = array(
'description' => __('Barcode', 'woocommerce-pos'),
'description' => __( 'Barcode', 'woocommerce-pos' ),
'type' => 'string',
'context' => array('view', 'edit'),
'context' => array( 'view', 'edit' ),
'readonly' => false,
);
}

// Check for 'stock_quantity' and allow decimal
if ($this->wcpos_allow_decimal_quantities() &&
isset($schema['properties']['stock_quantity']) &&
\is_array($schema['properties']['stock_quantity'])) {
if ( $this->wcpos_allow_decimal_quantities() &&
isset( $schema['properties']['stock_quantity'] ) &&
\is_array( $schema['properties']['stock_quantity'] ) ) {
$schema['properties']['stock_quantity']['type'] = 'string';
}

Expand All @@ -76,14 +92,14 @@ public function get_item_schema() {
*/
public function get_collection_params() {
$params = parent::get_collection_params();

// Check if 'per_page' parameter exists and has a 'minimum' key before modifying
if (isset($params['per_page']) && \is_array($params['per_page'])) {
if ( isset( $params['per_page'] ) && \is_array( $params['per_page'] ) ) {
$params['per_page']['minimum'] = -1;
}

// Ensure 'orderby' is set and is an array before attempting to modify it
if (isset($params['orderby']['enum']) && \is_array($params['orderby']['enum'])) {
if ( isset( $params['orderby']['enum'] ) && \is_array( $params['orderby']['enum'] ) ) {
// Define new sorting options
$new_sort_options = array(
'sku',
Expand All @@ -92,9 +108,9 @@ public function get_collection_params() {
'stock_status',
);
// Merge new options, avoiding duplicates
$params['orderby']['enum'] = array_unique(array_merge($params['orderby']['enum'], $new_sort_options));
$params['orderby']['enum'] = array_unique( array_merge( $params['orderby']['enum'], $new_sort_options ) );
}

return $params;
}

Expand Down Expand Up @@ -155,7 +171,7 @@ public function wcpos_variation_response( WP_REST_Response $response, WC_Data $v
$data['parent_id'] = $variation->get_parent_id();
}
if ( ! isset( $data['name'] ) ) {
$data['name'] = \function_exists('wc_get_formatted_variation') ? wc_get_formatted_variation( $variation, true, false, false ) : '';
$data['name'] = \function_exists( 'wc_get_formatted_variation' ) ? wc_get_formatted_variation( $variation, true, false, false ) : '';
}

// Make sure we parse the meta data before returning the response
Expand Down Expand Up @@ -201,6 +217,21 @@ public function wcpos_get_all_posts( array $fields = array() ): array {
'fields' => 'ids',
);

if ( $this->wcpos_pos_only_products_enabled() ) {
$args['meta_query'] = array(
'relation' => 'OR',
array(
'key' => '_pos_visibility',
'compare' => 'NOT EXISTS',
),
array(
'key' => '_pos_visibility',
'value' => 'online_only',
'compare' => '!=',
),
);
}

$variation_query = new WP_Query( $args );

try {
Expand Down Expand Up @@ -255,6 +286,71 @@ protected function prepare_objects_query( $request ) {
}
}

// Add online_only check
if ( $this->wcpos_pos_only_products_enabled() ) {
$default_meta_query = array(
'relation' => 'OR',
array(
'key' => '_pos_visibility',
'compare' => 'NOT EXISTS',
),
array(
'key' => '_pos_visibility',
'value' => 'online_only',
'compare' => '!=',
),
);

if ( isset( $args['meta_query'] ) ) {
if ( ! isset( $args['meta_query']['relation'] ) ) {
$args['meta_query']['relation'] = 'AND';
}
$args['meta_query'] = array_merge_recursive( $args['meta_query'], $default_meta_query );
} else {
$args['meta_query'] = $default_meta_query;
}
};

return $args;
}

/**
* Endpoint for searching all product variations.
*
* @param WP_REST_Request $request Full details about the request.
*/
public function wcpos_get_all_items( $request ) {
// Prepare arguments for the product query
$args = array(
'post_type' => 'product_variation',
'posts_per_page' => 10, // Limit to 10 items per page
'orderby' => 'ID', // Default ordering
'order' => 'ASC',
'paged' => ! empty( $request['page'] ) ? $request['page'] : 1, // Handle pagination
);

// Check if 'search' param is set for SKU search
if ( ! empty( $request['search'] ) ) {
$args['meta_query'] = array(
array(
'key' => '_sku',
'value' => $request['search'],
'compare' => 'LIKE',
),
);
}

// Get product variations
$query = new WP_Query( $args );
$variations = array();

foreach ( $query->posts as $variation ) {
$object = new WC_Product_Variation( $variation->ID );
$response = $this->prepare_object_for_response( $object, $request );
$variations[] = $this->prepare_response_for_collection( $response );
}

// Return the response
return new WP_REST_Response( $variations, 200 );
}
}
94 changes: 67 additions & 27 deletions includes/Products.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ class Products {
public function __construct() {
add_action( 'woocommerce_product_set_stock', array( $this, 'product_set_stock' ) );
add_action( 'woocommerce_variation_set_stock', array( $this, 'product_set_stock' ) );
add_action( 'pre_get_posts', array( $this, 'hide_pos_products' ) );
// add_filter( 'woocommerce_get_product_subcategories_args', array( $this, 'filter_category_count_exclude_pos_only' ) );

$pos_only_products = woocommerce_pos_get_settings( 'general', 'pos_only_products' );

if ( $pos_only_products ) {
add_action( 'woocommerce_product_query', array( $this, 'hide_pos_only_products' ) );
add_filter( 'woocommerce_variation_is_visible', array( $this, 'hide_pos_only_variations' ), 10, 4 );
// add_filter( 'woocommerce_get_product_subcategories_args', array( $this, 'filter_category_count_exclude_pos_only' ) );
}

/**
* Allow decimal quantities for products and variations.
Expand All @@ -41,42 +47,76 @@ public function __construct() {
public function product_set_stock( $product ): void {
$post_modified = current_time( 'mysql' );
$post_modified_gmt = current_time( 'mysql', 1 );
wp_update_post(array(
'ID' => $product->get_id(),
'post_modified' => $post_modified,
'post_modified_gmt' => $post_modified_gmt,
));
wp_update_post(
array(
'ID' => $product->get_id(),
'post_modified' => $post_modified,
'post_modified_gmt' => $post_modified_gmt,
)
);
}

/**
* Hide POS Only products from the shop and category pages.
*
* @TODO - this should be improved so that admin users can see the product, but get a message
* @TODO - should I use the 'woocommerce_product_query' action instead? I found it doesn't work correctly
*
* @param WP_Query $query Query instance.
*
* @param mixed $query
* @return void
*/
public function hide_pos_products( $query ): void {
if ( ! is_admin() && $query->is_main_query() && ( 'product' === $query->get( 'post_type' ) || $query->is_tax( 'product_cat' ) ) ) {
$pos_only_products = woocommerce_pos_get_settings( 'general', 'pos_only_products' );
public function hide_pos_only_products( $query ) {
$meta_query = $query->get( 'meta_query' );

if ( $pos_only_products ) {
$meta_query = $query->get( 'meta_query' );
if ( ! \is_array( $meta_query ) ) {
$meta_query = array();
}
$meta_query['relation'] = 'OR';
$meta_query[] = array(
'key' => '_pos_visibility',
'value' => 'pos_only',
'compare' => '!=',
);
$meta_query[] = array(
'key' => '_pos_visibility',
'compare' => 'NOT EXISTS',
);
$query->set( 'meta_query', $meta_query );
// Define your default meta query.
$default_meta_query = array(
'relation' => 'OR',
array(
'key' => '_pos_visibility',
'value' => 'pos_only',
'compare' => '!=',
),
array(
'key' => '_pos_visibility',
'compare' => 'NOT EXISTS',
),
);

// Check if an existing meta query exists.
if ( is_array( $meta_query ) ) {
if ( ! isset( $meta_query ['relation'] ) ) {
$meta_query['relation'] = 'AND';
}
$meta_query[] = $default_meta_query;
} else {
$meta_query = $default_meta_query;
}

// Set the updated meta query back to the query.
$query->set( 'meta_query', $meta_query );
}

/**
* Remove POS Only variations from the storefront.
*
* @param bool $visible Whether the variation is visible.
* @param int $variation_id The variation ID.
* @param int $product_id The product ID.
* @param \WC_Product_Variation $variation The variation object.
*/
public function hide_pos_only_variations( $visible, $variation_id, $product_id, $variation ) {
if ( \is_shop() || \is_product_category() || \is_product() ) {
// Get the _pos_visibility meta value for the variation.
$pos_visibility = get_post_meta( $variation_id, '_pos_visibility', true );

// Check if _pos_visibility is 'pos_only' for this variation.
if ( $pos_visibility === 'pos_only' ) {
return false;
}
}

return $visible;
}

/**
Expand Down
Loading

0 comments on commit 458019f

Please sign in to comment.