Shortcode and get_template_part

Function get_template_part() load file only from theme directory (or child theme).
There is no filter or action hook that would change this behavior.

You will need to write your own get_template_part() variant to load files from the plugin directory (replace the locate_template() call from the original function). Or write an explicit:

$query->the_post();
include plugin_dir_path( __FILE__ ) . 'single-products.php';