# Flow zone presentation
 
![cross_sales_recommendations.png](7hdyz9cQQjjP)
 
Here are the main steps of that flow zone:
 
 - **Computing all the rules that are candidates for cross sales**: recipe [compute_cross_sales_candidate_rules](recipe:compute_cross_sales_candidate_rules) joins the dataset containing all cross sales consequents ([See the section about recommendations_preprocessing](article:45)) with dataset [valid_rules_denormalized_consequents](dataset:valid_rules_denormalized_consequents) to retrieve all the information of the rules that lead to that consequent ("rule_id" and rule metrics). This leads to the dataset [cross_sales_candidate_rules](dataset:cross_sales_candidate_rules). **We still talk at this stage about candidate rules** because all the rules retrieved with that join won't be actionable: to be, we need to ensure all the antecedents needed to trigger a rule were also purchased.
 
 - **Computing all the antecedents that are required to trigger candidate rules**: this is done by recipe [compute_cross_sales_required_antecedents](recipe:compute_cross_sales_required_antecedents)  that joins dataset [cross_sales_candidate_rules](dataset:cross_sales_candidate_rules) with [rules_denormalized_antecedents](dataset:rules_denormalized_antecedents)  ([What is that dataset ?](article:57)) to get dataset [cross_sales_required_antecedents](dataset:cross_sales_required_antecedents).
 
 - **Checking if the antecedents required to trigger candidate rules were purchased by customers**: this is done by recipe [compute_cross_sales_purchased_antecedents](recipe:compute_cross_sales_purchased_antecedents) that joins dataset [cross_sales_required_antecedents](dataset:cross_sales_required_antecedents) with dataset [customers_last_transactions_unique_items_prepared](dataset:customers_last_transactions_unique_items_prepared) and filters rows where antecedent items were purchased by customers. However, we don't yet know if all the antecedents required to trigger rules were purchased: that last information is computed in the two next recipes.
 
 - **Identifying the actionable rules**. It is done in two steps : 
   - **Pivoting the number of antecedents purchased at the "customer + rule" level**: this is done by recipe [compute_cross_sales_rules_summary](recipe:compute_cross_sales_rules_summary) and leads to the dataset [cross_sales_rules_summary](dataset:cross_sales_rules_summary) where the column "purchased_count" indicates the number of required antecedents purchased by the customer. 
   - **Checking if the number of required antecedents purchased matches the size of the rules' antecedents **: in that case, all the required antecedents of a rule are purchased and a rule becomes actionable. Recipe [compute_cross_sales_actionable_rules](recipe:compute_cross_sales_actionable_rules) does that check and only keeps the rules that could be activated for each customer. It leads to dataset [cross_sales_actionable_rules](dataset:cross_sales_actionable_rules).
 
- **Keeping only the best actionable rules for consequent itemsets**: multiple rules can lead to the same itemsets. Thus, it doesn't make sense to keep all of them and we only need to keep the best rule leading to each itemset. This notion of "best rule" depends on the rules metrics that you want to prioritize, and you will be able to configure it in the Dataiku application [Customers rules recommendations](article:53) section. Recipe [compute_cross_sales_best_actionable_rules](recipe:compute_cross_sales_best_actionable_rules) will take into account your metrics prioritization and keep, for each customer, the best rule leading to an itemset.
 
- **Keeping only the best actionable rule for consequent items**: an itemset ([I don't remember the difference between "Item" and "Itemset"](article:21)) is composed of multiple items. Thus, even if we isolated the best rules leading to itemsets, many could lead to the same items recommendations.
  - Recipe [compute_cross_sales_recommendations](recipe:compute_cross_sales_recommendations) is in charge of denormalizing rules consequents so that we get a dataset granularity of "1 row = 1 consequent item of 1 rule proposed to 1 customer".
  - Finally, recipe [compute_cross_sales_best_recommendations](recipe:compute_cross_sales_best_recommendations) follows your metrics prioritization to isolate the best rules leading to each item, for each customer.
 

