Here's the Gurobi code for the optimization problem.  The objective function is quadratic, and the constraints are a mix of linear and quadratic.

```python
from gurobipy import *

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

    # Create variables
    john = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="john")
    dale = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="dale")
    mary = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="mary")
    bobby = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="bobby")

    # Set objective
    obj = 4*john*john + 9*john*dale + 8*john*mary + 9*john*bobby + 2*dale*dale + 3*dale*mary + 5*dale*bobby + 4*mary*mary + mary*bobby + 6*bobby*bobby + 5*john + 6*dale + mary + 9*bobby
    model.setObjective(obj, GRB.MAXIMIZE)

    # Add constraints based on provided resources/attributes (these are redundant given the individual constraints below)
    # likelihood_to_quit = {'john': 2, 'dale': 1, 'mary': 9, 'bobby': 12}
    # paperwork_competence = {'john': 12, 'dale': 6, 'mary': 5, 'bobby': 13}
    # organization_score = {'john': 14, 'dale': 6, 'mary': 11, 'bobby': 11}

    # Add constraints based on the problem description
    model.addConstr(2*john*john + dale*dale + mary*mary >= 10)
    model.addConstr(2*john + dale + 12*bobby >= 10)
    model.addConstr(dale + 9*mary + 12*bobby >= 10)
    model.addConstr(2*john + dale + 9*mary >= 12)
    model.addConstr(2*john + dale + 12*bobby >= 12)
    model.addConstr(dale*dale + 9*mary*mary + 12*bobby*bobby >= 12)
    model.addConstr(2*john*john + dale*dale + 9*mary*mary >= 11)
    model.addConstr(2*john*john + dale*dale + 12*bobby*bobby >= 11)
    model.addConstr(dale + 9*mary + 12*bobby >= 11)
    model.addConstr(12*john + 6*dale >= 14)
    model.addConstr(12*john + 5*mary >= 15)
    model.addConstr(5*mary + 13*bobby >= 17)
    model.addConstr(12*john + 13*bobby >= 15)
    model.addConstr(14*john*john + 6*dale*dale >= 11)
    model.addConstr(6*dale + 11*mary >= 9)
    model.addConstr(6*dale + 11*bobby >= 19)
    model.addConstr(14*john*john + 11*mary*mary >= 14)
    model.addConstr(2*john - 2*mary - 8*bobby >= 0)
    model.addConstr(dale + 12*bobby <= 35)
    model.addConstr(2*john*john + 9*mary*mary <= 56)
    model.addConstr(2*john*john + 12*bobby*bobby <= 45)
    model.addConstr(dale + 9*mary <= 62)
    model.addConstr(9*mary*mary + 12*bobby*bobby <= 56)
    model.addConstr(2*john + dale <= 52)
    model.addConstr(dale*dale + 9*mary*mary + 12*bobby*bobby <= 54)
    model.addConstr(2*john + dale + 9*mary <= 30)
    model.addConstr(2*john + dale + 12*bobby <= 55)
    model.addConstr(2*john + dale + 9*mary + 12*bobby <= 55)
    model.addConstr(6*dale + 5*mary <= 47)
    model.addConstr(12*john*john + 6*dale*dale <= 27)
    model.addConstr(5*mary*mary + 13*bobby*bobby <= 89)
    model.addConstr(12*john*john + 6*dale*dale + 5*mary*mary <= 52)
    model.addConstr(6*dale*dale + 5*mary*mary + 13*bobby*bobby <= 62)
    model.addConstr(12*john + 6*dale + 5*mary + 13*bobby <= 62)
    model.addConstr(11*mary + 11*bobby <= 96)
    model.addConstr(6*dale*dale + 11*bobby*bobby <= 36)
    model.addConstr(14*john + 11*mary <= 93)
    model.addConstr(6*dale*dale + 11*mary*mary <= 29)
    model.addConstr(14*john + 6*dale + 11*mary + 11*bobby <= 29)


    # Optimize model
    model.optimize()

    if model.status == GRB.OPTIMAL:
        print('Obj: %g' % model.objVal)
        print('John: %g' % john.x)
        print('Dale: %g' % dale.x)
        print('Mary: %g' % mary.x)
        print('Bobby: %g' % bobby.x)
    elif model.status == GRB.INFEASIBLE:
        print('The model is infeasible.')
    else:
        print('Optimization ended with status %d' % model.status)


except GurobiError as e:
    print('Error code ' + str(e.errno) + ": " + str(e))

except AttributeError:
    print('Encountered an attribute error')
```