Skip to content

Commit

Permalink
add custom product compatibility fields
Browse files Browse the repository at this point in the history
  • Loading branch information
Sidsector9 committed Feb 26, 2024
1 parent 89ce3c3 commit b0d7592
Show file tree
Hide file tree
Showing 13 changed files with 38,049 additions and 27,542 deletions.
17 changes: 17 additions & 0 deletions includes/Admin/Product_Editor_Compatibility.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace WooCommerce\Square\Admin;

use Automattic\WooCommerce\Utilities\FeaturesUtil;
use Automattic\WooCommerce\Admin\Features\ProductBlockEditor\BlockRegistry;
use Automattic\WooCommerce\Internal\Admin\Features\ProductBlockEditor\ProductTemplates\ProductBlock;
use Automattic\WooCommerce\Internal\Admin\Features\ProductBlockEditor\ProductTemplates\Section;
use WooCommerce\Square\Handlers\Product;
Expand All @@ -13,6 +14,11 @@ public function __construct() {
return;
}

add_action(
'init',
array( $this, 'register_custom_blocks' )
);

add_filter(
'woocommerce_rest_prepare_product_object',
array( $this, 'add_data_to_product_response' ),
Expand Down Expand Up @@ -43,6 +49,17 @@ public function __construct() {
);
}

/**
* Registers the custom product field blocks.
*/
public function register_custom_blocks() {
if ( isset( $_GET['page'] ) && 'wc-admin' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
BlockRegistry::get_instance()->register_block_type_from_metadata( WC_SQUARE_PLUGIN_PATH . '/build/admin/product-blocks/stock-management-field' );
BlockRegistry::get_instance()->register_block_type_from_metadata( WC_SQUARE_PLUGIN_PATH . '/build/admin/product-blocks/stock-quantity-field' );
BlockRegistry::get_instance()->register_block_type_from_metadata( WC_SQUARE_PLUGIN_PATH . '/build/admin/product-blocks/sync-with-square-field' );
}
}

/**
* Adds pre-orders meta to the product response.
*
Expand Down
65,176 changes: 37,636 additions & 27,540 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@woocommerce/dependency-extraction-webpack-plugin": "^1.4.0",
"@woocommerce/eslint-plugin": "^1.1.0",
"@wordpress/env": "^8.1.0",
"@wordpress/scripts": "^13.0.2",
"@wordpress/scripts": "^24.6.0",
"config": "^1.24.0",
"cross-env": "^3.0.0",
"dotenv": "^16.0.3",
Expand Down Expand Up @@ -69,7 +69,9 @@
"wp_org_slug": "woocommerce-square"
},
"dependencies": {
"@wordpress/data": "^8.1.0",
"@woocommerce/product-editor": "^1.4.0",
"@wordpress/data": "^7.6.0",
"html-react-parser": "^5.1.7",
"uuid": "^9.0.1"
}
}
26 changes: 26 additions & 0 deletions src/admin/product-blocks/stock-management-field/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "woocommerce-square/stock-management-field",
"version": "0.1.0",
"title": "Square stock management field",
"category": "widgets",
"icon": "flag",
"description": "A block to add stock management field to the product editor.",
"supports": {
"html": false,
"inserter": false
},
"attributes": {
"disabled": {
"type": "boolean",
"default": false
},
"disabledCopy": {
"type": "string",
"default": ""
}
},
"textdomain": "woocommerce-square",
"editorScript": "file:./index.js"
}
55 changes: 55 additions & 0 deletions src/admin/product-blocks/stock-management-field/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { BaseControl, ToggleControl } from '@wordpress/components';
import { useEffect } from '@wordpress/element';
import {
__experimentalUseProductEntityProp as useProductEntityProp,
} from '@woocommerce/product-editor';
import parse from 'html-react-parser';

export const Edit = ( { attributes, context: { postType } } ) => {
const {
disabled,
disabledCopy,
} = attributes;

const [ manageStock, setManageStock ] = useProductEntityProp( 'manage_stock', { postType } );
const [ isSquareSynced, setIsSquareSynced ] = useProductEntityProp( 'is_square_synced', { postType } );
const [ isInventorySyncEnabled ] = useProductEntityProp( 'is_inventory_sync_enabled', { postType } );
const [ isSyncEnabled ] = useProductEntityProp( 'is_sync_enabled', { postType } );
const [ sku ] = useProductEntityProp( 'sku', { postType } );
let label = __( 'Track quantity for this product', 'woocommerce' );
let helpText = '';

useEffect( () => {
if ( sku.length ) {
return;
}

setIsSquareSynced( false );
}, [ sku ] );

if ( isSquareSynced && isSyncEnabled && sku.length ) {
label = <a href="/wp-admin/admin.php?page=wc-settings&tab=square">{ __( 'Synced with Square', 'woocommerce-square' ) }</a>
}

if ( disabled && disabledCopy ) {
helpText = parse( disabledCopy );
}

return (
<>
<BaseControl label={ __( 'Stock management', 'woocommerce-square' ) }>
<ToggleControl
label={ label }
disabled={ disabled || ( isSquareSynced && isInventorySyncEnabled && isSyncEnabled && sku.length ) }
help={ helpText }
checked={ manageStock }
onChange={ setManageStock }
/>
</BaseControl>
</>
);
};
30 changes: 30 additions & 0 deletions src/admin/product-blocks/stock-management-field/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* External dependencies
*/
import { registerProductEditorBlockType } from '@woocommerce/product-editor';

/**
* Internal dependencies
*/
import { Edit } from './edit';
import blockConfiguration from './block.json';

const { name, ...metadata } = blockConfiguration;
const settings = {
example: {},
edit: Edit,
};


/**
* Every block starts by registering a new block type definition.
*
* @see https://developer.wordpress.org/block-editor/developers/block-api/#registering-a-block
*/
registerProductEditorBlockType(
{
name,
metadata: metadata as never,
settings: settings as never,
}
);
17 changes: 17 additions & 0 deletions src/admin/product-blocks/stock-quantity-field/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "woocommerce-square/stock-quantity-field",
"version": "0.1.0",
"title": "Square stock quantity field",
"category": "widgets",
"icon": "flag",
"description": "A block to add stock quantity field to the product editor.",
"supports": {
"html": false,
"inserter": false
},
"attributes": {},
"textdomain": "woocommerce-square",
"editorScript": "file:./index.js"
}
148 changes: 148 additions & 0 deletions src/admin/product-blocks/stock-quantity-field/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**
* External dependencies
*/
import { useWooBlockProps } from '@woocommerce/block-templates';
import { useInstanceId } from '@wordpress/compose';
import { useEntityProp } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { createElement, useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import {
BaseControl,
__experimentalInputControl as InputControl,
Button
} from '@wordpress/components';
import {
useValidation,
__experimentalUseProductEntityProp as useProductEntityProp,
} from '@woocommerce/product-editor';

export function Edit( {
attributes,
clientId,
context,
} ) {
const blockProps = useWooBlockProps( attributes );
const stockQuantityId = useInstanceId(
BaseControl,
'product_stock_quantity'
);

const [ manageStock ] = useProductEntityProp( 'manage_stock', context.postType );
const [ stockQuantity, setStockQuantity ] = useProductEntityProp( 'stock_quantity', context.postType );
const [ productId ] = useProductEntityProp( 'id', context.postType );
const [ isSquareSynced ] = useProductEntityProp( 'is_square_synced', context.postType );
const [ isSyncEnabled ] = useProductEntityProp( 'is_sync_enabled', context.postType );
const [ isInventorySyncEnabled ] = useProductEntityProp( 'is_inventory_sync_enabled', context.postType );
const [ fetchStockNonce ] = useProductEntityProp( 'fetch_stock_nonce', context.postType );
const [ sor ] = useProductEntityProp( 'sor', context.postType );
const [ fetchStockProgress, setFetchStockProgress ] = useState( false );
const [ isQuantityDisabled, setIsQuantityDisabled ] = useState( true );
const isSavingPost = useSelect( ( __select ) => __select( 'core/editor' ).isSavingPost() );


const {
ref: stockQuantityRef,
error: stockQuantityValidationError,
validate: validateStockQuantity,
} = useValidation(
`stock_quantity-${ clientId }`,
async function stockQuantityValidator() {
if ( manageStock && stockQuantity && stockQuantity < 0 ) {
return __(
'Stock quantity must be a positive number.',
'woocommerce-square'
);
}
},
[ manageStock, stockQuantity ]
);

useEffect( () => {
if ( manageStock && stockQuantity === null ) {
setStockQuantity( 1 );
}
}, [ manageStock, stockQuantity ] );

if ( ! manageStock ) {
return null;
}

async function fetchStockFromSquare() {
const fetchStockData = new FormData();

fetchStockData.append( 'action', 'wc_square_fetch_product_stock_with_square' );
fetchStockData.append( 'security', fetchStockNonce );
fetchStockData.append( 'product_id', productId );

setFetchStockProgress( true );

let response = await fetch( window.ajaxurl, {
method: 'POST',
body: fetchStockData,
} );

response = await response.json();

if ( response.success ) {
const { quantity, manage_stock: manageStock } = response.data;

setIsQuantityDisabled( false );
setStockQuantity( Number( quantity ) );
}

setFetchStockProgress( false );
}

return (
<div { ...blockProps }>
<div className="wp-block-columns">
<div className="wp-block-column">
<BaseControl
id={ stockQuantityId }
className={
stockQuantityValidationError && 'has-error'
}
help={ stockQuantityValidationError ?? '' }
>
<InputControl
id={ stockQuantityId }
name="stock_quantity"
ref={ stockQuantityRef }
label={ __( 'Available quantity', 'woocommerce-square' ) }
value={ stockQuantity }
onChange={ setStockQuantity }
onBlur={ validateStockQuantity }
type="number"
min={ 0 }
disabled={ isSquareSynced && manageStock && isQuantityDisabled }
/>
{
isSyncEnabled && isInventorySyncEnabled && isSquareSynced && manageStock && 'square' === sor && (
<p>
<a href="#">
{ `${ __( 'Managed by Square', 'woocommerce-square' ) } (${ __( 'Sync stock from Square', 'woocommerce-square' ) })` }
</a>
</p>
)
}

{
isSyncEnabled && isInventorySyncEnabled && isSquareSynced && manageStock && 'woocommerce' === sor && (
<p>
<Button
variant='link'
text={ __( 'Fetch stock from Square', 'woocommerce-square' ) }
onClick={ fetchStockFromSquare }
isBusy={ fetchStockProgress }
/>
</p>
)
}
</BaseControl>
</div>
<div className="wp-block-column" />
</div>
</div>
);
}
30 changes: 30 additions & 0 deletions src/admin/product-blocks/stock-quantity-field/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* External dependencies
*/
import { registerProductEditorBlockType } from '@woocommerce/product-editor';

/**
* Internal dependencies
*/
import { Edit } from './edit';
import blockConfiguration from './block.json';

const { name, ...metadata } = blockConfiguration;
const settings = {
example: {},
edit: Edit,
};


/**
* Every block starts by registering a new block type definition.
*
* @see https://developer.wordpress.org/block-editor/developers/block-api/#registering-a-block
*/
registerProductEditorBlockType(
{
name,
metadata: metadata as never,
settings: settings as never,
}
);
17 changes: 17 additions & 0 deletions src/admin/product-blocks/sync-with-square-field/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "woocommerce-square/sync-with-square-field",
"version": "0.1.0",
"title": "Sync with Square checkbox field",
"category": "widgets",
"icon": "flag",
"description": "A block to add a checkbox to set the sync with Square product setting.",
"attributes": {},
"supports": {
"html": false,
"inserter": false
},
"textdomain": "woocommerce-square",
"editorScript": "file:./index.js"
}
Loading

0 comments on commit b0d7592

Please sign in to comment.