Here's the Gurobi code that models and solves the optimization problem:

```python
from gurobipy import Model, GRB

# Create a new model
model = Model("optimization_problem")

# Create variables
kale_salads = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="kale_salads")
rotisserie_chickens = model.addVar(lb=0, vtype=GRB.INTEGER, name="rotisserie_chickens")
potatoes = model.addVar(lb=0, vtype=GRB.INTEGER, name="potatoes")
blueberry_pies = model.addVar(lb=0, vtype=GRB.INTEGER, name="blueberry_pies")

# Set objective function
model.setObjective(3 * kale_salads + 7 * rotisserie_chickens + 7 * potatoes + 5 * blueberry_pies, GRB.MINIMIZE)

# Add constraints
model.addConstr(8 * kale_salads + 2 * potatoes >= 3, "c1")
model.addConstr(2 * potatoes + 6 * blueberry_pies >= 6, "c2")
model.addConstr(8 * rotisserie_chickens + 6 * blueberry_pies >= 8, "c3")
model.addConstr(8 * kale_salads + 8 * rotisserie_chickens >= 10, "c4")
model.addConstr(8 * kale_salads + 8 * rotisserie_chickens + 2 * potatoes + 6 * blueberry_pies >= 10, "c5")
model.addConstr(7 * kale_salads + 7 * potatoes >= 10, "c6")
model.addConstr(2 * rotisserie_chickens + 2 * blueberry_pies >= 18, "c7")
model.addConstr(2 * rotisserie_chickens + 7 * potatoes >= 9, "c8")
model.addConstr(7 * kale_salads + 2 * blueberry_pies >= 15, "c9")
model.addConstr(7 * kale_salads + 2 * rotisserie_chickens + 2 * blueberry_pies >= 25, "c10")
model.addConstr(7 * kale_salads + 2 * rotisserie_chickens + 7 * potatoes + 2 * blueberry_pies >= 25, "c11")
model.addConstr(2 * kale_salads - potatoes >= 0, "c12")
model.addConstr(10 * rotisserie_chickens - 6 * potatoes >= 0, "c13")

# Sourness index upper bound constraints
model.addConstr(8 * kale_salads + 2 * potatoes <= 21, "c14")
model.addConstr(8 * kale_salads + 8 * rotisserie_chickens <= 12, "c15")
model.addConstr(8 * kale_salads + 8 * rotisserie_chickens + 2 * potatoes <= 12, "c16")
model.addConstr(8 * kale_salads + 2 * potatoes + 6 * blueberry_pies <= 43, "c17")

# Tastiness rating upper bound constraints
model.addConstr(2 * rotisserie_chickens + 2 * blueberry_pies <= 90, "c18")
model.addConstr(7 * kale_salads + 2 * rotisserie_chickens + 2 * blueberry_pies <= 47, "c19")


# Global sourness and tastiness constraints (from the provided resource dictionary)
model.addConstr(8 * kale_salads + 8 * rotisserie_chickens + 2 * potatoes + 6 * blueberry_pies <= 47, "global_sourness")
model.addConstr(7 * kale_salads + 2 * rotisserie_chickens + 7 * potatoes + 2 * blueberry_pies <= 110, "global_tastiness")


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print('Obj: ', model.objVal)
    for v in model.getVars():
        print(f"{v.varName}: {v.x}")
elif model.status == GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {model.status}")

```
