feat: category filter, item reference SKU lookup, brand sync, and on-demand BC write-back

- Filter product sync to an allow-list of BC item category codes
- Look up items by ReferenciasArticulo item reference before falling back to GTIN/item number
- Sync BC item category to product_brand and parent category to product_cat via a new ItemCategoryHierarchy endpoint
- Add on-demand push of product name/photo back to BC (product edit meta box + bulk action), including binary PATCH support for item pictures

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-09 11:39:11 +02:00
parent 6a541de9e6
commit 0aff5cf6d8
5 changed files with 655 additions and 5 deletions

View File

@@ -498,4 +498,67 @@ class WBC_API_Client {
return self::get( '/items', $params );
}
/**
* PATCH raw binary content to an endpoint (e.g. item picture upload)
*
* @param string $endpoint API endpoint (e.g. '/items(id)/picture/pictureContent').
* @param string $binary_data Raw binary body.
* @param string $content_type MIME type of the binary content.
* @return true|WP_Error True on success (204), or error.
*/
public static function patch_binary( $endpoint, $binary_data, $content_type ) {
$token = WBC_OAuth::get_access_token();
if ( is_wp_error( $token ) ) {
return $token;
}
$url = self::build_url( $endpoint, true );
WBC_Logger::debug( 'API', 'PATCH binary request', array( 'url' => $url, 'content_type' => $content_type ) );
$ch = curl_init();
curl_setopt_array( $ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => self::TIMEOUT,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => $binary_data,
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer ' . $token,
'Content-Type: ' . $content_type,
'If-Match: *',
),
) );
$response = curl_exec( $ch );
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
$curl_error = curl_error( $ch );
curl_close( $ch );
if ( $response === false ) {
WBC_Logger::error( 'API', 'cURL error on binary PATCH', array( 'error' => $curl_error, 'url' => $url ) );
return new WP_Error( 'wbc_curl_error', $curl_error );
}
if ( $http_code >= 400 ) {
$data = json_decode( $response, true );
$error_message = isset( $data['error']['message'] ) ? $data['error']['message'] : __( 'API request failed', 'woo-business-central' );
WBC_Logger::error( 'API', 'Binary PATCH failed', array(
'http_code' => $http_code,
'error' => $data['error'] ?? null,
'url' => $url,
) );
return new WP_Error( 'wbc_api_error', $error_message, array( 'status' => $http_code ) );
}
WBC_Logger::debug( 'API', 'Binary PATCH successful', array( 'http_code' => $http_code, 'url' => $url ) );
return true;
}
}