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

```python
import gurobipy as gp

# Create a new model
m = gp.Model("work_hours")

# Create variables
paul_hours = m.addVar(lb=0, name="paul_hours")
hank_hours = m.addVar(lb=0, name="hank_hours")

# Set objective function
m.setObjective(6 * paul_hours + 4 * hank_hours, gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(13 * paul_hours + 3 * hank_hours >= 8, "organization_score_min")
m.addConstr(6 * paul_hours + 14 * hank_hours >= 29, "likelihood_to_quit_min")
m.addConstr(6 * paul_hours + 13 * hank_hours >= 7, "dollar_cost_min")
m.addConstr(11 * paul_hours + 11 * hank_hours >= 17, "paperwork_rating_min")
m.addConstr(4 * paul_hours - 7 * hank_hours >= 0, "custom_constraint")

m.addConstr(13 * paul_hours + 3 * hank_hours <= 42, "organization_score_max")
m.addConstr(6 * paul_hours + 14 * hank_hours <= 42, "likelihood_to_quit_max")
m.addConstr(6 * paul_hours + 13 * hank_hours <= 38, "dollar_cost_max")
m.addConstr(11 * paul_hours + 11 * hank_hours <= 20, "paperwork_rating_max")


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Optimal objective value:', m.objVal)
    print('Paul hours:', paul_hours.x)
    print('Hank hours:', hank_hours.x)
elif m.status == gp.GRB.INFEASIBLE:
    print('Model is infeasible')
else:
    print('Optimization ended with status:', m.status)

```
