XiaoFaye / WooCommerce.NET

A .NET Wrapper for WooCommerce/WordPress REST API
MIT License
394 stars 219 forks source link

Unable to filter products #662

Closed fredoche1810 closed 1 year ago

fredoche1810 commented 3 years ago

Hello, I looking for a solution to find a product by the function GetAll(Dictionary). Even what I try I always receive all the products as result I want to add to my Dictionary a filter to select the products with some values coming from the meta_data created with the plugin Advanced Custom Field. The values of the fields are visible in the result of the product returned by the API.

here is my code : Dictionary<string, string> myDict = new Dictionary<string, string>(); myDict.Add("meta", "true"); myDict.Add("meta_key", "id_article_mercator"); myDict.Add("meta_value", "80348"); List p = await wc.Product.GetAll(myDict);

With the dictionary are without the result is exact the same.

Please let we know how to make the filter by dictionary working.

Or is there a way to add the filter possibility by customizing the API of woocommerce for example by an override ?

Thanks in advance,

Fred

bulkasergei commented 2 years ago

Try to use Linq for filtering ,for example Get the list of products and then filter it var query = await Task.Run(() => { return product.Where(x => x.id == "11545"); }); Or make your exstention method for WCObject .

fredoche1810 commented 2 years ago

@bulkasergei Returning all the products and than filtering is also very hard… when I will have 40.000 products it will be a very long request and answer and then filtering it. The best way was to be able to filter on a field. Is there a possibility to add a custom field in the database for example “ownid” on the products and then to ask the products that have some value in this field ? In prestashop, it was possible by an override on the webservice, so I suppose there is a solution for woocommerce too. I will have the same issue for the categories. As I want to sync my erp and woocommerce, I need to add a field with the unique id of my erp to find the product or the category back to update it if it exists or to create it if not. thanks in advance,

bulkasergei commented 2 years ago

My apoligies if i am not fully understood your qestion. but i see in your dictionary myDict.Add("meta_key", "id_article_mercator"); i guess this is not correct key and value which you trying to filter. for example to filter product by slug you have to add dict.Add("slug", "keyboard-a4tech-keyboard-kls-5"); or by status dict.Add("status", "publish"); etc.

fredoche1810 commented 2 years ago

@bulkasergei No problem it could be not well explained… By the dictionary you can filter some fields from the first level but how to add a custom field that you can use in the rest api filter ? I added my custom field with the module advanced custom field and I can find it in the response of the webservice but I can’t filter on it. The difference with that field is that it’s situated under meta_data not directly at the first level.

So how can I add a custom field for example status2 in case of status, that I can use with the webservice. Filter it, update it and so on ?

I suppose there is an override to add somewhere to include the field in the response, add the possibility to update it

bulkasergei commented 2 years ago

You have some additional properties which is not bound by this awesome package correct? just create additional class and derive from WooCommerceNET.WooCommerce.v3.Product, for your model for example bellow public class ProductsX: WooCommerceNET.WooCommerce.v3.Product { public string featured_image {get; set;} } and use serialization for addition filed . after get all prod use ext method

public static async Task<ObservableCollection< ProductsX >> GetAllProdExt(this WCObject item, RestAPI API, Dictionary<string, string> parms = null) { var result = API.DeserializeJSon<ObservableCollection< ProductsX >>(await API.GetRestful(item.Product.APIEndpoint.APIEndpoint, parms).ConfigureAwait(false)); return result; } somthing like this. you have serialization issue i guess.

fredoche1810 commented 2 years ago

Hello, Sorry but we aren't talking about the same I think. Before to be able to do something with the api, it has to work basically Insomnia for example. So when I try to filter my product with this url https://mysite.com/wp-json/wc/v3/products I can't filter anything. I always receive the result with all the products. I have to add some code in my functions.php file to add the possibility to filter inside the meta-key. In the result i can see a acf group with the custom fields image

So what can I put as code in my functions.php file to be able to use this link ? https://mysite.com/wp-json/wc/v3/products?id_article_mercator=80348

Thanks in advance,

bulkasergei commented 2 years ago

Hello, as i mentioned before, you have extra property which is not included by default. If you want to get all products by WooCommerce.NET and include your extra property you have to do bellow:

public class ProductsX : WooCommerceNET.WooCommerce.v3.Product
    {
      //import  using System.Runtime.Serialization;
        [DataMember(EmitDefaultValue = false)]
       public AdditionalProperty acf { get; set; }
    }

public class AdditionalProperty
{
   [DataMember(EmitDefaultValue = false)]
   public string id_article_mercator { get; set; }
   [DataMember(EmitDefaultValue = false)]
   public string id_category_mercator { get; set; }
}

//create extension method 
public static class WooCommerceExt
{
public static async Task<ObservableCollection<ProductsX>> GetAllExt(this WCItem<ProductsX> item, RestAPI API, Dictionary<string, string> parms = null)
      {
          var result = API.DeserializeJSon<ObservableCollection<ProductsX>>(await API.GetRestful(item.APIEndpoint, parms).ConfigureAwait(false));

          return result;
      }
}
   static class Program
 {
      static async Task Main(string[] args)
        {

            WooCommerceNET.Base.WCItem<ProductsX> wC = new WooCommerceNET.Base.WCItem<ProductsX>(rest);
             Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("slug", "w-i");
             var listproducts = await wC.GetAllExt(rest,dic );
            var query = listproducts.Where(x => x.acf.id_article_mercator.id == "80348").ToList();
            foreach (var item in query)
            {
                Console.WriteLine(item.name);
            }

             Console.ReadKey();
        }

}

You will get extra property and you can filter products by Linq. For parameters in which you can List all products from API refer http://woocommerce.github.io/woocommerce-rest-api-docs/?php#list-all-products
this is default parameters and this parameters you can pass in Dictionary. What about your extra object acf to list products. suggest to search in plugin documentation. Hope this will help you!

fredoche1810 commented 2 years ago

Hello, Thanks for your help. Now I can read an extra value not included by default.

Next problem that I have : how to create a product including this extra field ? I receive an error on this extra field : image

Isn't there any code to add in the functions.php file to also include this new field in the REST Api ?

Thanks in advance,

bulkasergei commented 2 years ago

Hi :) you not creating instance of Class. typo error :)) it should be like this var p = new ProductsX { name = "sample", //bla bla all fields

acf.id_article_meractor = new "class name here" { id = "bla bla", somemore_filed = "bla bla"}

};

fredoche1810 commented 2 years ago

Hi, You are right. Thanks. When I use the class I don't have any error anymore.

image

But unfortunnatelly, the value inserted isn't saved ... As you can see the name is changed : image

But the ACF value isn't saved image

What could be the reason? Thanks,

bulkasergei commented 2 years ago

Hi! :) I am assuming that you missing to put in attribute Name prop. let me know your contact info.

fredoche1810 commented 2 years ago

Hello @bulkasergei, Thanks for your help. I finally solve it. I add the value with the metadata and it seems to work : image Thanks,

safvanak commented 2 years ago
  • Wordpress version : 5.8.1
  • WooCommerce version : 5.8.0
  • WooCommerce.NET version : 0.8.3

Hello, I looking for a solution to find a product by the function GetAll(Dictionary). Even what I try I always receive all the products as result I want to add to my Dictionary a filter to select the products with some values coming from the meta_data created with the plugin Advanced Custom Field. The values of the fields are visible in the result of the product returned by the API.

here is my code : Dictionary<string, string> myDict = new Dictionary<string, string>(); myDict.Add("meta", "true"); myDict.Add("meta_key", "id_article_mercator"); myDict.Add("meta_value", "80348"); List p = await wc.Product.GetAll(myDict);

With the dictionary are without the result is exact the same.

Please let we know how to make the filter by dictionary working.

Or is there a way to add the filter possibility by customizing the API of woocommerce for example by an override ?

Thanks in advance,

Fred

Hi have you got any solution for this, I am also stuck with the same issue , I need to filter order list

fredoche1810 commented 2 years ago

Hi @safvanak, I reach to filter products or products categories on ACF fields but I didn't try on order list until now. On which field do you want to filter the order list ?

richardaubin commented 2 years ago

@fredoche1810 I would love to have an implementation of your code to filter on meta_data by key and value... any chance you can help me out?