## Step 1: Define the symbolic representation of the problem
The problem involves maximizing an objective function subject to several constraints. Let's define the symbolic variables:
- $x_0$ = hours worked by Dale
- $x_1$ = hours worked by Peggy
- $x_2$ = hours worked by George
- $x_3$ = hours worked by Bobby

## Step 2: Translate the objective function into symbolic notation
The objective function to maximize is: $4.89x_0 + 2.71x_1 + 2.84x_2 + 2.81x_3$

## 3: List the constraints in symbolic notation
Given resources/attributes:
- $r_0$: work quality rating
- $r_1$: productivity rating

With their respective values:
- $r_0$: $1.32x_0 + 6.87x_1 + 2.77x_2 + 1.19x_3$
- $r_1$: $3.76x_0 + 9.8x_1 + 7.93x_2 + 12.05x_3$

Constraints:
1. $2.77x_2 + 1.19x_3 \geq 36$
2. $6.87x_1 + 1.19x_3 \geq 40$
3. $7.93x_2 + 12.05x_3 \geq 14$
4. $3.76x_0 + 9.8x_1 \geq 19$
5. $2.77x_2 + 1.19x_3 \leq 109$
6. $6.87x_1 + 2.77x_2 \leq 70$
7. $6.87x_1 + 2.77x_2 + 1.19x_3 \leq 157$
8. $1.32x_0 + 2.77x_2 + 1.19x_3 \leq 72$
9. $1.32x_0 + 6.87x_1 + 2.77x_2 + 1.19x_3 \leq 72$
10. $7.93x_2 + 12.05x_3 \leq 134$
11. $3.76x_0 + 9.8x_1 \leq 70$
12. $3.76x_0 + 12.05x_3 \leq 113$
13. $9.8x_1 + 12.05x_3 \leq 138$
14. $3.76x_0 + 9.8x_1 + 12.05x_3 \leq 142$
15. $9.8x_1 + 7.93x_2 + 12.05x_3 \leq 84$
16. $3.76x_0 + 9.8x_1 + 7.93x_2 \leq 57$
17. $3.76x_0 + 9.8x_1 + 7.93x_2 + 12.05x_3 \leq 57$

## 4: Define the symbolic representation of the problem in JSON format
```json
{
    'sym_variables': [('x0', 'hours worked by Dale'), ('x1', 'hours worked by Peggy'), ('x2', 'hours worked by George'), ('x3', 'hours worked by Bobby')],
    'objective_function': '4.89*x0 + 2.71*x1 + 2.84*x2 + 2.81*x3',
    'constraints': [
        '2.77*x2 + 1.19*x3 >= 36',
        '6.87*x1 + 1.19*x3 >= 40',
        '7.93*x2 + 12.05*x3 >= 14',
        '3.76*x0 + 9.8*x1 >= 19',
        '2.77*x2 + 1.19*x3 <= 109',
        '6.87*x1 + 2.77*x2 <= 70',
        '6.87*x1 + 2.77*x2 + 1.19*x3 <= 157',
        '1.32*x0 + 2.77*x2 + 1.19*x3 <= 72',
        '1.32*x0 + 6.87*x1 + 2.77*x2 + 1.19*x3 <= 72',
        '7.93*x2 + 12.05*x3 <= 134',
        '3.76*x0 + 9.8*x1 <= 70',
        '3.76*x0 + 12.05*x3 <= 113',
        '9.8*x1 + 12.05*x3 <= 138',
        '3.76*x0 + 9.8*x1 + 12.05*x3 <= 142',
        '9.8*x1 + 7.93*x2 + 12.05*x3 <= 84',
        '3.76*x0 + 9.8*x1 + 7.93*x2 <= 57',
        '3.76*x0 + 9.8*x1 + 7.93*x2 + 12.05*x3 <= 57',
        'x0 >= 0', 'x1 >= 0', 'x2 >= 0', 'x3 >= 0',
        'x0 % 1 == 0', 'x1 % 1 == 0', 'x2 % 1 == 0', 'x3 % 1 == 0'
    ]
}
```

## 5: Implement the optimization problem using Gurobi
```python
import gurobi

def solve_optimization_problem():
    model = gurobi.Model()

    # Define variables
    x0 = model.addVar(name="x0", vtype=gurobi.GRB.INTEGER)  # hours worked by Dale
    x1 = model.addVar(name="x1", vtype=gurobi.GRB.INTEGER)  # hours worked by Peggy
    x2 = model.addVar(name="x2", vtype=gurobi.GRB.INTEGER)  # hours worked by George
    x3 = model.addVar(name="x3", vtype=gurobi.GRB.INTEGER)  # hours worked by Bobby

    # Objective function
    model.setObjective(4.89*x0 + 2.71*x1 + 2.84*x2 + 2.81*x3, gurobi.GRB.MAXIMIZE)

    # Constraints
    model.addConstr(2.77*x2 + 1.19*x3 >= 36)
    model.addConstr(6.87*x1 + 1.19*x3 >= 40)
    model.addConstr(7.93*x2 + 12.05*x3 >= 14)
    model.addConstr(3.76*x0 + 9.8*x1 >= 19)
    model.addConstr(2.77*x2 + 1.19*x3 <= 109)
    model.addConstr(6.87*x1 + 2.77*x2 <= 70)
    model.addConstr(6.87*x1 + 2.77*x2 + 1.19*x3 <= 157)
    model.addConstr(1.32*x0 + 2.77*x2 + 1.19*x3 <= 72)
    model.addConstr(1.32*x0 + 6.87*x1 + 2.77*x2 + 1.19*x3 <= 72)
    model.addConstr(7.93*x2 + 12.05*x3 <= 134)
    model.addConstr(3.76*x0 + 9.8*x1 <= 70)
    model.addConstr(3.76*x0 + 12.05*x3 <= 113)
    model.addConstr(9.8*x1 + 12.05*x3 <= 138)
    model.addConstr(3.76*x0 + 9.8*x1 + 12.05*x3 <= 142)
    model.addConstr(9.8*x1 + 7.93*x2 + 12.05*x3 <= 84)
    model.addConstr(3.76*x0 + 9.8*x1 + 7.93*x2 <= 57)
    model.addConstr(3.76*x0 + 9.8*x1 + 7.93*x2 + 12.05*x3 <= 57)
    model.addConstr(x0 >= 0)
    model.addConstr(x1 >= 0)
    model.addConstr(x2 >= 0)
    model.addConstr(x3 >= 0)

    # Solve the model
    model.optimize()

    # Print the solution
    if model.status == gurobi.GRB.OPTIMAL:
        print("Objective: ", model.objVal)
        print("Hours worked by Dale: ", x0.varValue)
        print("Hours worked by Peggy: ", x1.varValue)
        print("Hours worked by George: ", x2.varValue)
        print("Hours worked by Bobby: ", x3.varValue)
    else:
        print("The model is infeasible")

solve_optimization_problem()
```