Okay
  Public Ticket #4560014
Dynamic Rules: Get Sale Products
Closed

Comments

  • Ilya started the conversation

    How can I get all sale products on the site, taking into account discounts from dynamic rules?

    I reviewed the B2BKing classes, particularly B2bking_Globalhelper, and found a function for retrieving all dynamic rules, as well as fetching “global data” via:

    B2bking_Globalhelper::get_global_data(false, false, $user_id);
    

    Inside this function, I noticed some keys related to product IDs, such as:

    • b2bking_discount_everywhere
    • b2bking_discount_everywhere_parent
    • b2bking_discount_everywhere_user_applicable_rules

    Could you please explain what these array keys represent?

    And overall, could you help me figure out how to properly retrieve all sale products for a specific user, so I can later pass this array of products further in the logic?

  •  2,724
    WebWizards replied

    Hi Ilya,

    Thanks for reaching out.

     

    To point you in the right direction, could you please share more about what you're actually building? The best approach really depends on the use case.

    For example:
    - If your goal is just to get an array of on-sale products for the currently logged-in user, the simplest way is to use wc_get_products() and then loop through them checking $product->is_on_sale(). With B2BKing active, sale status already takes dynamic rules into account for the logged-in user.
    - If you're building something like an admin portal where the admin can see which rules apply to each specific user, that would need a very different approach.
    Also:
    - Do you only need the list of products on sale, or do you also need the exact discount amount / percentage per product?
    - Approx. how many products and rules will the site have? (just rough numbers, is it more than 1000? more than 100,000?)

     

    Once I understand what you're trying to achieve, I'd be happy to go into the details, including the meaning of those keys you mentioned.

    Kind regards,
    Stefan

  • Ilya replied

    I want to create a separate “Sale” page where discounted products will be displayed.
    I also want to add a product filter for discounted items only, and when filtering within a category, show only discounted products.

  •  2,724
    WebWizards replied

    Hi Ilya,

    Thanks for the follow-up.

    For your use case, I'd recommend the following approach:

    1. Get all products (or the products of the current category) using wc_get_products().
    2. Loop through them and check $product->is_on_sale(). With B2BKing active, this already takes dynamic rules into account for the logged-in user.
    3. Cache the results in a transient whose name starts with b2bking_. That way our system will automatically clear it when rules or products change.

    Here's an example shortcode that lists on-sale products and works with B2BKing: https://pastecode.io/s/pz5qh37a

    I recommend the same approach for the product filter: get all products first, then filter by is_on_sale().

     

    Regarding the internal keys you found: I'd recommend against going that route unless you really need maximum performance and are prepared to spend some time working on it and testing. Those keys are only an intermediate stage in the calculation, not a final list of sale products. If you really wanted to go that way, the logic would roughly be:

    (A) Read b2bking_have_discount_everywhere_rules_list_ids_elements, this contains info such as: "user_234" has a discount rule applicable to products 100, 250, 356 ; "all_registered" has discount rules applicable to products 300, 400, etc. We refer to these kind of notation "user_234", "all_registered", "group_123" etc as "elements".
    (B) Calculate the current user's applicable elements. Each user will have (user_123, group_456, all_registered, everyone_registered_b2b or everyone_registered_b2c) and compare the elements of the user against that key.
    (C) Merge those candidate IDs with wc_get_product_ids_on_sale() to also catch regular on sale products, not just those from B2BKing
    (D) Finally, run $product->is_on_sale() only on that merged candidate set. This is still needed because the rules also have conditions, so we need this final safety check. Therefore this way you are still checking $product->is_on_sale(), just starting with a smaller list, not from wc_get_products().

     

    Kind regards,
    Stefan