Here's the Gurobi code to solve your optimization problem.  We define the variables, objective function, and constraints based on your input. The code also includes variable integrality constraints.

```python
from gurobipy import Model, GRB

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

# Create variables
jean = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Jean")
mary = model.addVar(lb=0, vtype=GRB.INTEGER, name="Mary")
bobby = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Bobby")
dale = model.addVar(lb=0, vtype=GRB.INTEGER, name="Dale")
ringo = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Ringo")

# Set objective function
model.setObjective(1 * jean + 9 * mary + 3 * bobby + 7 * dale + 2 * ringo, GRB.MAXIMIZE)

# Resource constraints
resources = {
    'r0': {'upper_bound': 230, 'coeffs': [3, 18, 18, 21, 5]},  # computer competence
    'r1': {'upper_bound': 191, 'coeffs': [1, 21, 20, 2, 2]},  # productivity
    'r2': {'upper_bound': 287, 'coeffs': [8, 13, 1, 5, 7]},  # dollar cost
    'r3': {'upper_bound': 223, 'coeffs': [12, 14, 21, 22, 10]}  # work quality
}

for resource, data in resources.items():
    model.addConstr(
        data['coeffs'][0] * jean + data['coeffs'][1] * mary + data['coeffs'][2] * bobby + data['coeffs'][3] * dale + data['coeffs'][4] * ringo <= data['upper_bound'],
        name=f"{resource}_constraint"
    )

# Additional constraints (simplified to avoid redundancy)
model.addConstr(18 * mary + 21 * dale + 5 * ringo >= 41) # Computer competence
model.addConstr(3 * jean + 18 * bobby + 5 * ringo >= 41) # Computer competence
model.addConstr(3 * jean + 18 * bobby + 21 * dale >= 41) # Computer competence
model.addConstr(3 * jean + 18 * mary + 18 * bobby >= 41) # Computer competence
model.addConstr(3 * jean + 18 * mary + 21 * dale >= 41) # Computer competence

model.addConstr(21 * mary + 20 * bobby >= 15) # Productivity
model.addConstr(2 * dale + 2 * ringo >= 15) # Productivity
model.addConstr(1 * jean + 2 * ringo >= 36) # Productivity
model.addConstr(21 * mary + 2 * ringo >= 29) # Productivity
model.addConstr(21 * mary + 2 * dale >= 33) # Productivity
model.addConstr(1 * jean + 2 * dale >= 17) # Productivity
model.addConstr(1 * jean + 21 * mary + 2 * dale >= 38) # Productivity


model.addConstr(13 * mary + 1 * bobby <= 140) # Dollar cost
model.addConstr(8 * jean + 13 * mary <= 241) # Dollar cost
model.addConstr(5 * dale + 7 * ringo <= 95) # Dollar cost
model.addConstr(1 * bobby + 7 * ringo <= 252) # Dollar cost
model.addConstr(13 * mary + 5 * dale <= 99) # Dollar cost
model.addConstr(8 * jean + 5 * dale <= 211) # Dollar cost
model.addConstr(8 * jean + 7 * ringo <= 62) # Dollar cost
model.addConstr(1 * bobby + 5 * dale <= 139) # Dollar cost
model.addConstr(8 * jean + 13 * mary + 1 * bobby + 5 * dale + 7 * ringo <= 139) # Dollar cost

model.addConstr(12 * jean + 14 * mary >= 42) # Work quality
model.addConstr(12 * jean + 10 * ringo >= 31) # Work quality
model.addConstr(21 * bobby + 22 * dale >= 27) # Work quality
model.addConstr(14 * mary + 22 * dale >= 15) # Work quality


model.addConstr(18 * mary + 18 * bobby <= 214) # Computer competence
model.addConstr(18 * bobby + 5 * ringo <= 70) # Computer competence
model.addConstr(3 * jean + 18 * mary <= 88) # Computer competence

model.addConstr(21 * mary + 2 * dale <= 116) # Productivity
model.addConstr(1 * jean + 20 * bobby <= 182) # Productivity
model.addConstr(20 * bobby + 2 * dale <= 82) # Productivity
model.addConstr(2 * dale + 2 * ringo <= 134) # Productivity
model.addConstr(21 * mary + 2 * ringo <= 150) # Productivity
model.addConstr(1 * jean + 21 * mary + 20 * bobby + 2 * dale + 2 * ringo <= 150) # Productivity

model.addConstr(21 * bobby + 10 * ringo <= 55) # Work quality
model.addConstr(12 * jean + 22 * dale <= 195) # Work quality
model.addConstr(12 * jean + 14 * mary + 21 * bobby + 22 * dale + 10 * ringo <= 195) # Work quality


# Optimize model
model.optimize()

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

```