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

```python
from gurobipy import Model, GRB

# Create a new model
model = Model("Resource Allocation")

# Create variables
black_pens = model.addVar(vtype=GRB.INTEGER, name="black_pens")
headsets = model.addVar(vtype=GRB.INTEGER, name="headsets")
mechanical_pencils = model.addVar(vtype=GRB.INTEGER, name="mechanical_pencils")
lanyards = model.addVar(vtype=GRB.INTEGER, name="lanyards")

# Set objective function
model.setObjective(4 * black_pens + 4 * headsets + 8 * mechanical_pencils + 9 * lanyards, GRB.MINIMIZE)

# Add constraints
model.addConstr(20 * headsets + 2 * lanyards >= 51, "c1")
model.addConstr(9 * black_pens + 20 * headsets + 10 * mechanical_pencils >= 90, "c2")
model.addConstr(9 * black_pens + 20 * headsets + 10 * mechanical_pencils + 2 * lanyards >= 90, "c3")
model.addConstr(16 * headsets + 7 * lanyards >= 28, "c4")
model.addConstr(16 * headsets + 17 * mechanical_pencils >= 45, "c5")
model.addConstr(17 * mechanical_pencils + 7 * lanyards >= 66, "c6")
model.addConstr(10 * black_pens + 16 * headsets + 17 * mechanical_pencils + 7 * lanyards >= 66, "c7")
model.addConstr(16 * black_pens + 9 * lanyards >= 73, "c8")
model.addConstr(16 * black_pens + 1 * mechanical_pencils >= 72, "c9")
model.addConstr(16 * black_pens + 12 * headsets >= 56, "c10")
model.addConstr(12 * headsets + 1 * mechanical_pencils >= 62, "c11")
model.addConstr(16 * black_pens + 12 * headsets + 1 * mechanical_pencils + 9 * lanyards >= 62, "c12")
model.addConstr(-7 * black_pens + 3 * headsets >= 0, "c13")
model.addConstr(9 * black_pens + 2 * lanyards <= 261, "c14")
model.addConstr(10 * mechanical_pencils + 2 * lanyards <= 341, "c15")
model.addConstr(20 * headsets + 2 * lanyards <= 153, "c16")
model.addConstr(20 * headsets + 10 * mechanical_pencils <= 136, "c17")
model.addConstr(9 * black_pens + 10 * mechanical_pencils <= 100, "c18")
model.addConstr(9 * black_pens + 20 * headsets + 2 * lanyards <= 182, "c19")
model.addConstr(9 * black_pens + 20 * headsets + 10 * mechanical_pencils <= 208, "c20")
model.addConstr(10 * black_pens + 17 * mechanical_pencils <= 180, "c21")
model.addConstr(10 * black_pens + 16 * headsets <= 281, "c22")
model.addConstr(10 * black_pens + 7 * lanyards <= 197, "c23")
model.addConstr(10 * black_pens + 16 * headsets + 17 * mechanical_pencils <= 107, "c24")
model.addConstr(10 * black_pens + 16 * headsets + 7 * lanyards <= 216, "c25")
model.addConstr(16 * black_pens + 9 * lanyards <= 332, "c26")
model.addConstr(12 * headsets + 1 * mechanical_pencils <= 309, "c27")
model.addConstr(16 * black_pens + 12 * headsets <= 235, "c28")


# Resource Constraints (provided in the prompt)
model.addConstr(9 * black_pens + 20 * headsets + 10 * mechanical_pencils + 2 * lanyards <= 374, "r0") #sustainability score
model.addConstr(10 * black_pens + 16 * headsets + 17 * mechanical_pencils + 7 * lanyards <= 300, "r1") #workplace safety impact
model.addConstr(16 * black_pens + 12 * headsets + 1 * mechanical_pencils + 9 * lanyards <= 412, "r2") #usefulness rating


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print('\nCost: %g' % model.objVal)
    for v in model.getVars():
        print('%s %g' % (v.varName, v.x))
else:
    print("Infeasible")

```
