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

```python
import gurobipy as gp

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

# Create variables
george = m.addVar(lb=0, name="George")
jean = m.addVar(lb=0, name="Jean")
dale = m.addVar(lb=0, name="Dale")
ringo = m.addVar(lb=0, name="Ringo")
bill = m.addVar(lb=0, name="Bill")

# Set objective function
m.setObjective(1 * george + 4 * jean + 2 * dale + 4 * ringo + 8 * bill, gp.GRB.MAXIMIZE)

# Add constraints based on provided data
resource_data = {
    'r0': {'description': 'dollar cost per hour', 'upper_bound': 261, 'x0': 1.29, 'x1': 1.38, 'x2': 4.64, 'x3': 3.93, 'x4': 2.49},
    'r1': {'description': 'computer competence rating', 'upper_bound': 149, 'x0': 5.04, 'x1': 3.74, 'x2': 0.56, 'x3': 5.86, 'x4': 1.07},
    'r2': {'description': 'likelihood to quit index', 'upper_bound': 99, 'x0': 5.22, 'x1': 1.67, 'x2': 3.29, 'x3': 2.74, 'x4': 4.63}
}

# Cost constraints
m.addConstr(3.93 * ringo + 2.49 * bill >= 18)
m.addConstr(4.64 * dale + 2.49 * bill >= 41)
m.addConstr(1.38 * jean + 3.93 * ringo + 2.49 * bill >= 47)
m.addConstr(1.38 * jean + 4.64 * dale + 2.49 * bill >= 47)
m.addConstr(1.38 * jean + 3.93 * ringo + 2.49 * bill >= 43)
m.addConstr(1.38 * jean + 4.64 * dale + 2.49 * bill >= 43)
m.addConstr(3.93 * ringo + 2.49 * bill <= 129)
m.addConstr(1.29 * george + 1.38 * jean <= 207)
m.addConstr(4.64 * dale + 3.93 * ringo <= 214)
m.addConstr(1.29 * george + 1.38 * jean + 4.64 * dale + 3.93 * ringo + 2.49 * bill <= 214)


# Competence constraints
m.addConstr(3.74 * jean + 1.07 * bill >= 12)
m.addConstr(5.04 * george + 3.74 * jean >= 15)
m.addConstr(3.74 * jean + 5.86 * ringo >= 14)
m.addConstr(0.56 * dale + 1.07 * bill >= 14)
m.addConstr(5.04 * george + 0.56 * dale >= 10)
m.addConstr(5.04 * george + 0.56 * dale + 1.07 * bill >= 16)
m.addConstr(5.04 * george + 3.74 * jean <= 94)
m.addConstr(3.74 * jean + 1.07 * bill <= 149)
m.addConstr(5.04 * george + 1.07 * bill <= 86)
m.addConstr(3.74 * jean + 0.56 * dale <= 124)
m.addConstr(5.04 * george + 5.86 * ringo <= 82)
m.addConstr(5.86 * ringo + 1.07 * bill <= 84)
m.addConstr(0.56 * dale + 1.07 * bill <= 87)
m.addConstr(5.04 * george + 3.74 * jean + 0.56 * dale + 5.86 * ringo + 1.07 * bill <= 87)


# Likelihood to quit constraints
m.addConstr(5.22 * george + 4.63 * bill <= 27)
m.addConstr(1.67 * jean + 2.74 * ringo <= 79)
m.addConstr(1.67 * jean + 3.29 * dale + 4.63 * bill <= 85)
m.addConstr(1.67 * jean + 3.29 * dale + 2.74 * ringo <= 45)
m.addConstr(5.22 * george + 1.67 * jean + 3.29 * dale <= 51)
m.addConstr(5.22 * george + 2.74 * ringo + 4.63 * bill <= 66)
m.addConstr(5.22 * george + 3.29 * dale + 4.63 * bill <= 54)
m.addConstr(1.67 * jean + 2.74 * ringo + 4.63 * bill <= 67)
m.addConstr(5.22 * george + 1.67 * jean + 2.74 * ringo <= 81)
m.addConstr(3.29 * dale + 2.74 * ringo + 4.63 * bill <= 42)
m.addConstr(5.22 * george + 1.67 * jean + 3.29 * dale + 2.74 * ringo + 4.63 * bill <= 42)



# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Obj: %g' % m.objVal)
    for v in m.getVars():
        print('%s %g' % (v.varName, v.x))
elif m.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print("Optimization ended with status %d" % m.status)

```
