```python
import gurobipy as gp
from gurobipy import GRB

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

# Create variables
hank_hours = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="hank_hours")
peggy_hours = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="peggy_hours")
mary_hours = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="mary_hours")
dale_hours = m.addVar(lb=0, vtype=GRB.INTEGER, name="dale_hours")

# Set objective function
m.setObjective(6*hank_hours**2 + 6*hank_hours*peggy_hours + 9*hank_hours*mary_hours + 2*peggy_hours**2 + 4*peggy_hours*mary_hours + 9*peggy_hours*dale_hours + 5*dale_hours**2 + 7*hank_hours + 7*peggy_hours + 7*mary_hours, GRB.MAXIMIZE)

# Add constraints based on provided resource attributes
productivity_rating = {'Hank': 7.78, 'Peggy': 4.57, 'Mary': 2.91, 'Dale': 5.28}
likelihood_to_quit = {'Hank': 7.7, 'Peggy': 8.32, 'Mary': 6.3, 'Dale': 8.37}
dollar_cost_per_hour = {'Hank': 1.01, 'Peggy': 0.91, 'Mary': 8.59, 'Dale': 4.06}
computer_competence = {'Hank': 6.02, 'Peggy': 6.71, 'Mary': 2.0, 'Dale': 6.5}
work_quality = {'Hank': 3.38, 'Peggy': 8.21, 'Mary': 8.49, 'Dale': 6.87}


# Add provided constraints
m.addConstr(2.91*mary_hours**2 + 5.28*dale_hours**2 >= 18)
m.addConstr(7.78*hank_hours + 5.28*dale_hours >= 49)
m.addConstr(7.78*hank_hours**2 + 2.91*mary_hours**2 + 5.28*dale_hours**2 >= 31)
m.addConstr(7.78*hank_hours + 4.57*peggy_hours + 5.28*dale_hours >= 31)
m.addConstr(7.78*hank_hours + 2.91*mary_hours + 5.28*dale_hours >= 27)
m.addConstr(7.78*hank_hours + 4.57*peggy_hours + 5.28*dale_hours >= 27)

m.addConstr(7.7*hank_hours**2 + 8.32*peggy_hours**2 >= 43)
m.addConstr(8.32*peggy_hours + 8.37*dale_hours >= 17)
m.addConstr(6.3*mary_hours + 8.37*dale_hours >= 29)
m.addConstr(7.7*hank_hours + 6.3*mary_hours >= 32)
m.addConstr(8.32*peggy_hours**2 + 6.3*mary_hours**2 >= 25)
m.addConstr(8.32*peggy_hours + 6.3*mary_hours + 8.37*dale_hours >= 41)
m.addConstr(7.7*hank_hours + 8.32*peggy_hours + 8.37*dale_hours >= 41)
m.addConstr(7.7*hank_hours + 6.3*mary_hours + 8.37*dale_hours >= 41)
m.addConstr(8.32*peggy_hours + 6.3*mary_hours + 8.37*dale_hours >= 33)
m.addConstr(7.7*hank_hours**2 + 8.32*peggy_hours**2 + 8.37*dale_hours**2 >= 33)
m.addConstr(7.7*hank_hours + 6.3*mary_hours + 8.37*dale_hours >= 33)
m.addConstr(8.32*peggy_hours**2 + 6.3*mary_hours**2 + 8.37*dale_hours**2 >= 33)
m.addConstr(7.7*hank_hours + 8.32*peggy_hours + 8.37*dale_hours >= 33)
m.addConstr(7.7*hank_hours + 6.3*mary_hours + 8.37*dale_hours >= 33)


m.addConstr(1.01*hank_hours + 8.59*mary_hours >= 24)
m.addConstr(0.91*peggy_hours**2 + 4.06*dale_hours**2 >= 13)
m.addConstr(1.01*hank_hours + 4.06*dale_hours >= 19)
m.addConstr(8.59*mary_hours + 4.06*dale_hours >= 18)

m.addConstr(6.71*peggy_hours**2 + 2.0*mary_hours**2 >= 16)
m.addConstr(6.02*hank_hours**2 + 6.5*dale_hours**2 >= 29)
m.addConstr(2.0*mary_hours**2 + 6.5*dale_hours**2 >= 42)
m.addConstr(6.02*hank_hours + 2.0*mary_hours >= 32)


m.addConstr(8.21*peggy_hours**2 + 8.49*mary_hours**2 + 6.87*dale_hours**2 >= 16)
m.addConstr(3.38*hank_hours**2 + 8.21*peggy_hours**2 + 8.49*mary_hours**2 >= 16)
m.addConstr(8.21*peggy_hours**2 + 8.49*mary_hours**2 + 6.87*dale_hours**2 >= 17)
m.addConstr(3.38*hank_hours + 8.21*peggy_hours + 8.49*mary_hours >= 17)

#Upper Bound Constraints
m.addConstr(4.57*peggy_hours + 5.28*dale_hours <= 113)
m.addConstr(2.91*mary_hours + 5.28*dale_hours <= 109)
m.addConstr(7.78*hank_hours**2 + 2.91*mary_hours**2 <= 174)
m.addConstr(4.57*peggy_hours + 2.91*mary_hours <= 117)
m.addConstr(7.78*hank_hours + 5.28*dale_hours <= 139)
m.addConstr(4.57*peggy_hours**2 + 2.91*mary_hours**2 + 5.28*dale_hours**2 <= 132)
m.addConstr(7.78*hank_hours + 4.57*peggy_hours + 5.28*dale_hours <= 195)
m.addConstr(7.78*hank_hours + 4.57*peggy_hours + 2.91*mary_hours + 5.28*dale_hours <= 195)

m.addConstr(8.32*peggy_hours**2 + 6.3*mary_hours**2 <= 94)
m.addConstr(8.32*peggy_hours**2 + 8.37*dale_hours**2 <= 181)
m.addConstr(7.7*hank_hours + 8.32*peggy_hours <= 197)
m.addConstr(7.7*hank_hours + 8.32*peggy_hours + 6.3*mary_hours + 8.37*dale_hours <= 197)

m.addConstr(.91*peggy_hours + 8.59*mary_hours <= 31)
m.addConstr(1.01*hank_hours + 4.06*dale_hours <= 54)
m.addConstr(1.01*hank_hours + .91*peggy_hours + 8.59*mary_hours + 4.06*dale_hours <= 54)

m.addConstr(6.02*hank_hours + 6.71*peggy_hours <= 153)
m.addConstr(6.71*peggy_hours**2 + 2.0*mary_hours**2 <= 159)
m.addConstr(6.02*hank_hours + 2.0*mary_hours <= 152)
m.addConstr(6.02*hank_hours + 6.71*peggy_hours + 2.0*mary_hours + 6.5*dale_hours <= 152)

m.addConstr(8.49*mary_hours + 6.87*dale_hours <= 45)
m.addConstr(3.38*hank_hours + 8.49*mary_hours <= 61)
m.addConstr(8.21*peggy_hours + 8.49*mary_hours <= 54)
m.addConstr(3.38*hank_hours + 8.21*peggy_hours <= 96)
m.addConstr(3.38*hank_hours**2 + 8.49*mary_hours**2 + 6.87*dale_hours**2 <= 110)
m.addConstr(3.38*hank_hours + 8.21*peggy_hours + 8.49*mary_hours + 6.87*dale_hours <= 110)



# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print('Obj: %g' % m.objVal)
    print('Hank Hours: %g' % hank_hours.x)
    print('Peggy Hours: %g' % peggy_hours.x)
    print('Mary Hours: %g' % mary_hours.x)
    print('Dale Hours: %g' % dale_hours.x)
elif m.status == GRB.INFEASIBLE:
    print('Model is infeasible')
else:
    print('Optimization ended with status %d' % m.status)
```