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

```python
from gurobipy import Model, GRB

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

# Create variables
dale_hours = model.addVar(name="dale_hours", lb=0.0)  # Non-negative hours
hank_hours = model.addVar(name="hank_hours", lb=0.0)  # Non-negative hours

# Set objective function
model.setObjective(4 * dale_hours * dale_hours + 6 * dale_hours * hank_hours + 7 * dale_hours, GRB.MAXIMIZE)

# Add constraints
model.addConstr(4 * dale_hours + 4 * hank_hours >= 29, "min_competence")
model.addConstr(-8 * dale_hours + 6 * hank_hours >= 0, "hours_relation")
model.addConstr(4 * dale_hours + 4 * hank_hours <= 70, "max_competence") # Combined constraint


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print(f"Optimal solution found:")
    print(f"  Dale's hours: {dale_hours.x}")
    print(f"  Hank's hours: {hank_hours.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}.")

```
