To solve the given optimization problem, we will use the Gurobi Python interface. The problem involves minimizing a linear objective function subject to various constraints related to the sourness index and tastiness rating of different food items.

The decision variables are:
- `kale_salads`: amount of kale salads
- `rotisserie_chickens`: quantity of rotisserie chickens (integer)
- `potatoes`: number of potatoes (integer)
- `blueberry_pies`: number of blueberry pies (integer)

The objective function to minimize is: 
3 * `kale_salads` + 7 * `rotisserie_chickens` + 7 * `potatoes` + 5 * `blueberry_pies`

Constraints:
1. Sourness index constraints
2. Tastiness rating constraints
3. Mixed constraints involving sourness index and tastiness ratings

Here is the Gurobi code to solve this problem:

```python
from gurobipy import *

# Create a model
m = Model("Optimization_Problem")

# Define decision variables
kale_salads = m.addVar(vtype=GRB.CONTINUOUS, name="kale_salads")
rotisserie_chickens = m.addVar(vtype=GRB.INTEGER, name="rotisserie_chickens")
potatoes = m.addVar(vtype=GRB.INTEGER, name="potatoes")
blueberry_pies = m.addVar(vtype=GRB.INTEGER, name="blueberry_pies")

# Define the objective function
m.setObjective(3 * kale_salads + 7 * rotisserie_chickens + 7 * potatoes + 5 * blueberry_pies, GRB.MINIMIZE)

# Add constraints
m.addConstr(8 * kale_salads + 2 * potatoes >= 3, name="sourness_index_1")
m.addConstr(2 * potatoes + 6 * blueberry_pies >= 6, name="sourness_index_2")
m.addConstr(8 * rotisserie_chickens + 6 * blueberry_pies >= 8, name="sourness_index_3")
m.addConstr(8 * kale_salads + 8 * rotisserie_chickens >= 10, name="sourness_index_4")
m.addConstr(8 * kale_salads + 8 * rotisserie_chickens + 2 * potatoes + 6 * blueberry_pies >= 10, name="sourness_index_5")

m.addConstr(7 * kale_salads + 7 * potatoes >= 10, name="tastiness_rating_1")
m.addConstr(2 * rotisserie_chickens + 2 * blueberry_pies >= 18, name="tastiness_rating_2")
m.addConstr(2 * rotisserie_chickens + 7 * potatoes >= 9, name="tastiness_rating_3")
m.addConstr(7 * kale_salads + 2 * blueberry_pies >= 15, name="tastiness_rating_4")
m.addConstr(7 * kale_salads + 2 * rotisserie_chickens + 2 * blueberry_pies >= 25, name="tastiness_rating_5")
m.addConstr(7 * kale_salads + 2 * rotisserie_chickens + 7 * potatoes + 2 * blueberry_pies >= 25, name="tastiness_rating_6")

m.addConstr(2 * kale_salads - potatoes >= 0, name="mixed_constraint_1")
m.addConstr(10 * rotisserie_chickens - 6 * potatoes >= 0, name="mixed_constraint_2")

m.addConstr(8 * kale_salads + 2 * potatoes <= 21, name="sourness_index_max_1")
m.addConstr(8 * kale_salads + 8 * rotisserie_chickens <= 12, name="sourness_index_max_2")
m.addConstr(8 * kale_salads + 8 * rotisserie_chickens + 2 * potatoes <= 12, name="sourness_index_max_3")
m.addConstr(8 * kale_salads + 2 * potatoes + 6 * blueberry_pies <= 43, name="sourness_index_max_4")

m.addConstr(2 * rotisserie_chickens + 2 * blueberry_pies <= 90, name="tastiness_rating_max_1")
m.addConstr(7 * kale_salads + 2 * rotisserie_chickens + 2 * blueberry_pies <= 47, name="tastiness_rating_max_2")

# Optimize the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Kale Salads: {kale_salads.x}")
    print(f"Rotisserie Chickens: {rotisserie_chickens.x}")
    print(f"Potatoes: {potatoes.x}")
    print(f"Blueberry Pies: {blueberry_pies.x}")
else:
    print("No optimal solution found")
```