To solve the given optimization problem, we first need to convert the natural language description into a symbolic representation. Let's denote the number of perfume bottles as $x_1$ and the number of cologne bottles as $x_2$. The objective is to maximize profit, with each perfume bottle contributing $50 and each cologne bottle contributing $60 to the total profit.

The symbolic representation of the problem can be described as follows:
```json
{
  'sym_variables': [('x1', 'number of perfume bottles'), ('x2', 'number of cologne bottles')],
  'objective_function': '50*x1 + 60*x2',
  'constraints': [
    '2*x1 + 2.5*x2 <= 700',  # Time constraint
    'x1 >= 60',  # Minimum perfume bottles constraint
    'x2 >= 40'  # Minimum cologne bottles constraint
  ]
}
```
This representation captures the essence of the problem: maximizing profit ($50 for each perfume bottle and $60 for each cologne bottle) under the constraints of available time (700 minutes), with at least 60 perfume bottles and 40 cologne bottles to be filled.

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

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

# Define variables
x1 = m.addVar(vtype=GRB.INTEGER, name="perfume_bottles")
x2 = m.addVar(vtype=GRB.INTEGER, name="cologne_bottles")

# Set objective function
m.setObjective(50*x1 + 60*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(2*x1 + 2.5*x2 <= 700, "time_constraint")
m.addConstr(x1 >= 60, "min_perfume_bottles")
m.addConstr(x2 >= 40, "min_cologne_bottles")

# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Number of perfume bottles: {x1.x}")
    print(f"Number of cologne bottles: {x2.x}")
    print(f"Maximum profit: ${50*x1.x + 60*x2.x:.2f}")
else:
    print("No optimal solution found")
```