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

```python
import gurobipy as gp

# Create a new model
m = gp.Model("Minimize Labor Cost")

# Create variables
peggy_hours = m.addVar(name="peggy_hours", lb=0)  # Lower bound of 0 for hours
mary_hours = m.addVar(name="mary_hours", lb=0)
jean_hours = m.addVar(name="jean_hours", lb=0)

# Set objective function
m.setObjective(8 * peggy_hours + 2 * mary_hours + 3 * jean_hours, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(9 * mary_hours + 1 * jean_hours >= 7, "dollar_cost_mary_jean")
m.addConstr(12 * peggy_hours + 9 * mary_hours + 1 * jean_hours >= 7, "dollar_cost_total")
m.addConstr(2 * peggy_hours + 1 * mary_hours >= 10, "productivity_peggy_mary")
m.addConstr(1 * mary_hours + 10 * jean_hours >= 13, "productivity_mary_jean")
m.addConstr(2 * peggy_hours + 10 * jean_hours >= 16, "productivity_peggy_jean")
m.addConstr(2 * peggy_hours + 1 * mary_hours + 10 * jean_hours >= 16, "productivity_total")
m.addConstr(-8 * peggy_hours + 5 * mary_hours >= 0, "constraint_peggy_mary_relation")
m.addConstr(8 * mary_hours - 7 * jean_hours >= 0, "constraint_mary_jean_relation")
m.addConstr(2 * peggy_hours + 1 * mary_hours <= 32, "productivity_peggy_mary_upper")


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Optimal solution found:')
    print(f'Peggy hours: {peggy_hours.x}')
    print(f'Mary hours: {mary_hours.x}')
    print(f'Jean hours: {jean_hours.x}')
    print(f'Objective value: {m.objVal}')
elif m.status == gp.GRB.INFEASIBLE:
    print('Model is infeasible.')
else:
    print(f'Optimization ended with status {m.status}')

```
