To solve the given optimization problem, we first need to convert the natural language description into a symbolic representation. This involves defining variables for the quantities of bulldozers and forklifts to be produced, formulating the objective function that represents the total profit, and establishing the constraints based on the available assembly line and QC time.

Let's denote:
- \(x_1\) as the number of bulldozers to be made,
- \(x_2\) as the number of forklifts to be made.

The objective function, which aims to maximize the total profit, can be represented as:
\[7000x_1 + 6000x_2\]

The constraints are based on the available time for assembly and QC:
1. Assembly line time constraint: \(3x_1 + 2x_2 \leq 600\)
2. QC time constraint: \(2x_1 + 1.5x_2 \leq 400\)

Additionally, we have non-negativity constraints since the number of bulldozers and forklifts cannot be negative:
- \(x_1 \geq 0\)
- \(x_2 \geq 0\)

Thus, the symbolic representation of the problem is:
```json
{
    'sym_variables': [('x1', 'number of bulldozers'), ('x2', 'number of forklifts')],
    'objective_function': '7000*x1 + 6000*x2',
    'constraints': ['3*x1 + 2*x2 <= 600', '2*x1 + 1.5*x2 <= 400', 'x1 >= 0', 'x2 >= 0']
}
```

To solve this problem using Gurobi in Python, we can use the following code:
```python
from gurobipy import *

# Create a new model
m = Model("Construction_Company")

# Define variables
x1 = m.addVar(vtype=GRB.CONTINUOUS, name="bulldozers", lb=0)
x2 = m.addVar(vtype=GRB.CONTINUOUS, name="forklifts", lb=0)

# Set the objective function
m.setObjective(7000*x1 + 6000*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(3*x1 + 2*x2 <= 600, "assembly_line_time")
m.addConstr(2*x1 + 1.5*x2 <= 400, "qc_time")

# Optimize the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Number of bulldozers: {x1.x}")
    print(f"Number of forklifts: {x2.x}")
    print(f"Total profit: ${7000*x1.x + 6000*x2.x:.2f}")
else:
    print("No optimal solution found")
```