myparcelnl / woocommerce

MyParcel plug-in for WooCommerce
https://developer.myparcel.nl/nl/documentatie/10.woocommerce.html
MIT License
13 stars 21 forks source link

Additional fields not added to the rest interface #6

Open vankampenp opened 7 years ago

vankampenp commented 7 years ago

When using the Woocommerce Rest interface, the fields that the plug-in adds are not exposed. for example GET https://www.mysite.nl/wp-json/wc/v1/customers/1 delivers the standard WooCommerce output back, missing the added MyParcel fields. This means that you cannot retrieve the street and number. This is true for both customers and orders.

The following code extends the standard output with the MyParcel fields, both for viewing and for updating. The MyParcel fields added are "billing_street_name", "billing_house_number", "billing_house_number_suffix", "shipping_street_name", "shipping_house_number", "shipping_house_number_suffix"

Not sure where it best belongs in the plugin, but I suggest adding it so others don't have to spent the time figuring out how to get this. The code is called by the 'rest_api_init' action, so only when relevant.

add_action( 'rest_api_init', 'slug_register_myfields' );
function slug_register_myfields() {

  foreach( array( 'billing_street_name', 'billing_house_number','billing_house_number_suffix',
    'shipping_street_name', 'shipping_house_number','shipping_house_number_suffix') as $field ) {

    register_rest_field( 'customer', $field,
        array(
            'get_callback'    => 'get_customerMeta',
            'update_callback' => 'update_customerMeta',
            'schema'          => array(
        'description' => __( 'MyParcel fields', 'woocommerce' ),
        'type' => 'string',
        'context' => array( 'view', 'edit' ),
                        ),
        )
    );
  };

  foreach( array( 'billing_street_name', 'billing_house_number','billing_house_number_suffix',
        'shipping_street_name', 'shipping_house_number','shipping_house_number_suffix') as $field ) {
      register_rest_field( 'shop_order', $field,
           array(
               'get_callback'    =>'get_orderMeta',
               'update_callback' =>  'update_orderMeta',
            'schema'          => array(
                'description' => __( 'MyParcel fields', 'woocommerce' ),
                'type' => 'string',
                'context' => array( 'view', 'edit' ),
                ),
         )
       );
   };
}
function get_customerMeta($data,$field_name,$request) {
    return get_user_meta( $data[ 'id' ], $field_name, true );
};
function update_customerMeta($value,$data,$field_name) {
    if ( ! $value || ! is_string( $value ) ) return;
    update_user_meta( $data->ID, $field_name, sanitize_text_field( $value ) );
  };
function get_orderMeta($data,$field_name,$request) {
    return get_post_meta( $data[ 'id' ], '_' . $field_name, true );
};
function update_orderMeta($value,$data,$field_name) {
    if ( ! $value || ! is_string( $value ) ) return;
    update_post_meta( $data->ID, '_' . $field_name, sanitize_text_field( $value ) );
};  
RpairsKevin commented 7 years ago

In 2.x the shipping address is no longer set when using deliver to PostNL location/Pakjegemak. Is there a way to get the new shipping address for PostNL locations to work with the Rest API? Are there maybe new fields to add in a similar way?

Spreeuw commented 7 years ago

Here's an example filter that will add the pickup address to the rest API response (v2 in WC3.0):

add_filter( "woocommerce_rest_prepare_shop_order_object", "woocommerce_api_myparcel_delivery_options", 10, 3 );
function woocommerce_api_myparcel_delivery_options( $response, $order, $request ) {
    if( empty( $response->data ) ) {
        return $response;
    }

    $myparcel_delivery_options = $order->get_meta('_myparcel_delivery_options');
    if (!empty($myparcel_delivery_options) && isset($myparcel_delivery_options['location']) ) {
        $response->data['myparcel_pickup_address'] = array(
            'first_name'    => $order->get_shipping_first_name(),
            'last_name'     => $order->get_shipping_last_name(),
            'company'       => $myparcel_delivery_options['location'],
            'address_1'     => "{$myparcel_delivery_options['street']} {$myparcel_delivery_options['number']}",
            'address_2'     => '',
            'city'          => $myparcel_delivery_options['city'],
            'state'         => '',
            'postcode'      => $myparcel_delivery_options['postal_code'],
            'country'       => 'NL',
        );
    }

    return $response;

}

when using the legacy API you can use a similar filter (Again, for WC3.0):

add_filter( 'woocommerce_api_order_response', 'woocommerce_api_myparcel_delivery_options', 10, 2 );
function woocommerce_api_myparcel_delivery_options( $order_data, $order ) {
    $myparcel_delivery_options = $order->get_meta('_myparcel_delivery_options');
    if (!empty($myparcel_delivery_options) && isset($myparcel_delivery_options['location']) ) {
         $order_data['myparcel_pickup_address'] = array(
            'first_name'    => $order->get_shipping_first_name(),
            'last_name'     => $order->get_shipping_last_name(),
            'company'       => $myparcel_delivery_options['location'],
            'address_1'     => "{$myparcel_delivery_options['street']} {$myparcel_delivery_options['number']}",
            'address_2'     => '',
            'city'          => $myparcel_delivery_options['city'],
            'state'         => '',
            'postcode'      => $myparcel_delivery_options['postal_code'],
            'country'       => 'NL',
        );
    }

    return $order_data;
}

When using WC2.X, replace $order->get_meta and first_name & last_name calls with get_post_meta.

vankampenp commented 6 years ago

@Spreeuw If I understand this right, this creates new orders in WooCommerce with a proper filled address_1 line, is that correct? For existing customers in Wordpress, this does not actually provide the right address line, because it is not yet filled in address_1. So I need to find a way to update all existing customers, any suggestions?

Spreeuw commented 6 years ago

@vankampenp I'm no longer involved in the development of this plugin, @reindert-vetter or @RichardPerdaan may be able to help you with this though!