Here's the Gurobi code to solve your optimization problem:

```python
from gurobipy import Model, GRB

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

# Create variables
foods = ['peanutbutter sandwiches', 'oreos', 'kiwis', 'fruit salads', 'milkshakes', 'eggs']
x = model.addVars(foods, lb=0.0, vtype=GRB.CONTINUOUS, name=foods)

# Set objective function
model.setObjective(4.47 * x['peanutbutter sandwiches'] + 7.12 * x['oreos'] + 3.96 * x['kiwis'] + 7.26 * x['fruit salads'] + 9.54 * x['milkshakes'] + 7.14 * x['eggs'], GRB.MINIMIZE)

# Umami index data
umami_index = {'peanutbutter sandwiches': 14, 'oreos': 13, 'kiwis': 2, 'fruit salads': 4, 'milkshakes': 2, 'eggs': 11}
# Fat data
fat = {'peanutbutter sandwiches': 11, 'oreos': 5, 'kiwis': 14, 'fruit salads': 6, 'milkshakes': 13, 'eggs': 14}

# Umami index constraints
model.addConstr(14 * x['peanutbutter sandwiches'] + 4 * x['fruit salads'] >= 12)
model.addConstr(2 * x['kiwis'] + 2 * x['milkshakes'] >= 15)
model.addConstr(2 * x['kiwis'] + 4 * x['fruit salads'] >= 9)
model.addConstr(14 * x['peanutbutter sandwiches'] + 2 * x['kiwis'] >= 8)
model.addConstr(4 * x['fruit salads'] + 11 * x['eggs'] >= 6)
model.addConstr(14 * x['peanutbutter sandwiches'] + 2 * x['milkshakes'] >= 5)
model.addConstr(13 * x['oreos'] + 4 * x['fruit salads'] >= 5)
model.addConstr(14 * x['peanutbutter sandwiches'] + 11 * x['eggs'] >= 14)
model.addConstr(4 * x['fruit salads'] + 2 * x['milkshakes'] >= 6)
model.addConstr(13 * x['oreos'] + 2 * x['milkshakes'] >= 15)
model.addConstr(13 * x['oreos'] + 2 * x['milkshakes'] + 11 * x['eggs'] >= 15)
model.addConstr(sum(umami_index[f] * x[f] for f in foods) >= 15)


# Fat constraints
model.addConstr(14 * x['kiwis'] + 13 * x['milkshakes'] >= 50)
model.addConstr(6 * x['fruit salads'] + 14 * x['eggs'] >= 49)
model.addConstr(11 * x['peanutbutter sandwiches'] + 6 * x['fruit salads'] >= 57)
model.addConstr(14 * x['kiwis'] + 6 * x['fruit salads'] >= 21)
model.addConstr(13 * x['milkshakes'] + 14 * x['eggs'] >= 48)
model.addConstr(5 * x['oreos'] + 14 * x['eggs'] >= 39)
model.addConstr(5 * x['oreos'] + 13 * x['milkshakes'] >= 25)
model.addConstr(5 * x['oreos'] + 14 * x['kiwis'] >= 43)
model.addConstr(14 * x['kiwis'] + 14 * x['eggs'] >= 32)
model.addConstr(11 * x['peanutbutter sandwiches'] + 14 * x['eggs'] >= 37)
model.addConstr(sum(fat[f] * x[f] for f in foods) >= 37)

# Additional constraints
model.addConstr(2 * x['oreos'] - 4 * x['fruit salads'] >= 0)
model.addConstr(13 * x['oreos'] + 2 * x['kiwis'] + 4 * x['fruit salads'] <= 88)
model.addConstr(2 * x['kiwis'] + 2 * x['milkshakes'] + 11 * x['eggs'] <= 33)
model.addConstr(13 * x['oreos'] + 4 * x['fruit salads'] + 2 * x['milkshakes'] <= 53)
model.addConstr(2 * x['kiwis'] + 4 * x['fruit salads'] + 2 * x['milkshakes'] <= 29)
model.addConstr(13 * x['oreos'] + 2 * x['milkshakes'] + 11 * x['eggs'] <= 79)
model.addConstr(4 * x['fruit salads'] + 2 * x['milkshakes'] + 11 * x['eggs'] <= 97)
model.addConstr(14 * x['peanutbutter sandwiches'] + 4 * x['fruit salads'] + 2 * x['milkshakes'] <= 43)
model.addConstr(13 * x['oreos'] + 2 * x['kiwis'] + 2 * x['milkshakes'] <= 25)
model.addConstr(14 * x['peanutbutter sandwiches'] + 13 * x['oreos'] + 2 * x['kiwis'] <= 99)
model.addConstr(14 * x['peanutbutter sandwiches'] + 13 * x['oreos'] + 2 * x['milkshakes'] <= 51)
model.addConstr(2 * x['kiwis'] + 4 * x['fruit salads'] + 11 * x['eggs'] <= 44)
model.addConstr(13 * x['oreos'] + 2 * x['kiwis'] + 11 * x['eggs'] <= 35)
model.addConstr(13 * x['oreos'] + 4 * x['fruit salads'] + 11 * x['eggs'] <= 82)

model.addConstr(5 * x['oreos'] + 13 * x['milkshakes'] <= 369)
model.addConstr(11 * x['peanutbutter sandwiches'] + 14 * x['kiwis'] + 13 * x['milkshakes'] <= 386)
model.addConstr(11 * x['peanutbutter sandwiches'] + 13 * x['milkshakes'] + 14 * x['eggs'] <= 371)
model.addConstr(11 * x['peanutbutter sandwiches'] + 5 * x['oreos'] + 14 * x['kiwis'] <= 258)
model.addConstr(14 * x['kiwis'] + 6 * x['fruit salads'] + 13 * x['milkshakes'] <= 276)
model.addConstr(11 * x['peanutbutter sandwiches'] + 6 * x['fruit salads'] + 13 * x['milkshakes'] <= 194)


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    for f in foods:
        print(f"{f}: {x[f].x}")
    print(f"Objective value: {model.objVal}")
elif model.status == GRB.INFEASIBLE:
    print("Model is infeasible.")
else:
    print(f"Optimization terminated with status: {model.status}")

```
