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

```python
from gurobipy import Model, GRB

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

# Create variables
paul_hours = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Paul_Hours")
bill_hours = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Bill_Hours")
jean_hours = model.addVar(lb=0, vtype=GRB.INTEGER, name="Jean_Hours")

# Set objective function
model.setObjective(6 * paul_hours + 4 * bill_hours + 3 * jean_hours, GRB.MINIMIZE)

# Add constraints
model.addConstr(7 * paul_hours + 3 * jean_hours >= 31, "Paperwork_Paul_Jean")
model.addConstr(7 * paul_hours + 4 * bill_hours >= 20, "Paperwork_Paul_Bill")
model.addConstr(7 * paul_hours + 4 * bill_hours + 3 * jean_hours >= 31, "Paperwork_Total")
model.addConstr(12 * paul_hours + 12 * jean_hours >= 26, "Quality_Paul_Jean")
model.addConstr(12 * paul_hours + 2 * bill_hours >= 31, "Quality_Paul_Bill")
model.addConstr(12 * paul_hours + 2 * bill_hours + 12 * jean_hours >= 31, "Quality_Total")
model.addConstr(6 * paul_hours - bill_hours >= 0, "Paul_Bill_Ratio")
model.addConstr(4 * bill_hours - 5 * jean_hours >= 0, "Bill_Jean_Ratio")
model.addConstr(7 * paul_hours + 4 * bill_hours + 3 * jean_hours <= 84, "Paperwork_Total_Upper")
model.addConstr(12 * paul_hours + 2 * bill_hours + 12 * jean_hours <= 123, "Quality_Total_Upper")


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print('Optimal solution found')
    print(f"Paul's Hours: {paul_hours.x}")
    print(f"Bill's Hours: {bill_hours.x}")
    print(f"Jean's Hours: {jean_hours.x}")
    print(f"Objective Value: {model.objVal}")
elif model.status == GRB.INFEASIBLE:
    print('Model is infeasible')
else:
    print(f"Optimization ended with status {model.status}")

```
