Repository: Pyomo/pyomo

Issue:
`_collect_linear()` does not account for fixed variables' coefficients
`_collect_linear()` is not computing the `constant` term correctly when fixed variables have coefficients. This is resulting in the wrong LP file being written when using `quicksum()` (or `LinearExpression`s in general) in constraint rules.

### Current

```python
for c,v in zip(exp.linear_coefs, exp.linear_vars):
    if v.fixed:
        if compute_values:
            ans.constant += multiplier*v.value
        else:
            ans.constant += multiplier*v
    ...
```

### Suggested

```python
for c,v in zip(exp.linear_coefs, exp.linear_vars):
    if v.fixed:
        if compute_values:
            ans.constant += multiplier * c * value(v)
        else:
            ans.constant += multiplier * c * v
    ...
```


Discussion:

Resolving patch:
diff --git a/pyomo/repn/standard_repn.py b/pyomo/repn/standard_repn.py
--- a/pyomo/repn/standard_repn.py
+++ b/pyomo/repn/standard_repn.py
@@ -867,9 +867,9 @@ def _collect_linear(exp, multiplier, idMap, compute_values, verbose, quadratic):
     for c,v in zip(exp.linear_coefs, exp.linear_vars):
         if v.fixed:
             if compute_values:
-                ans.constant += multiplier*v.value
+                ans.constant += multiplier * value(c) * value(v)
             else:
-                ans.constant += multiplier*v
+                ans.constant += multiplier * c * v
         else:
             id_ = id(v)
             if id_ in idMap[None]:


Test patch:
diff --git a/pyomo/repn/tests/test_standard.py b/pyomo/repn/tests/test_standard.py
--- a/pyomo/repn/tests/test_standard.py
+++ b/pyomo/repn/tests/test_standard.py
@@ -4000,7 +4000,7 @@ def test_linear1(self):
         m = ConcreteModel()
         m.A = RangeSet(5)
         m.v = Var(m.A, initialize=1)
-        m.p = Param(m.A, initialize={1:-2, 2:-1, 3:0, 4:1, 5:2})
+        m.p = Param(m.A, initialize={1: -2, 2: -1, 3: 0, 4: 1, 5: 2})
 
         e = summation(m.v) + sum_product(m.p, m.v)
         rep = generate_standard_repn(e, compute_values=True)
@@ -4008,11 +4008,42 @@ def test_linear1(self):
         rep = generate_standard_repn(e, compute_values=False)
         self.assertEqual(str(rep.to_expression()), "- v[1] + v[3] + 2*v[4] + 3*v[5]")
 
-        m.v[1].fixed=True
+        m.v[1].fixed = True
+        rep = generate_standard_repn(e, compute_values=True)
+        self.assertEqual(str(rep.to_expression()), "-1 + v[3] + 2*v[4] + 3*v[5]")
+        rep = generate_standard_repn(e, compute_values=False)
+        self.assertEqual(
+            str(rep.to_expression()), "v[1] - 2*v[1] + v[3] + 2*v[4] + 3*v[5]"
+        )
+
+    def test_linear_with_mutable_param_and_fixed_var(self):
+        m = ConcreteModel()
+        m.A = RangeSet(5)
+        m.v = Var(m.A, initialize=1)
+        m.p = Param(m.A, initialize={1: -2, 2: -1, 3: 0, 4: 1, 5: 2}, mutable=True)
+
+        with EXPR.linear_expression() as expr:
+            for i in m.A:
+                expr += m.p[i] * m.v[i]
+
+        e = summation(m.v) + expr
+
+        rep = generate_standard_repn(e, compute_values=True)
+        self.assertEqual(str(rep.to_expression()), "- v[1] + v[3] + 2*v[4] + 3*v[5]")
+        rep = generate_standard_repn(e, compute_values=False)
+        self.assertEqual(
+            str(rep.to_expression()),
+            "(1 + p[1])*v[1] + (1 + p[2])*v[2] + (1 + p[3])*v[3] + (1 + p[4])*v[4] + (1 + p[5])*v[5]",
+        )
+
+        m.v[1].fixed = True
         rep = generate_standard_repn(e, compute_values=True)
-        self.assertEqual(str(rep.to_expression()), "2 + v[3] + 2*v[4] + 3*v[5]")
+        self.assertEqual(str(rep.to_expression()), "-1 + v[3] + 2*v[4] + 3*v[5]")
         rep = generate_standard_repn(e, compute_values=False)
-        self.assertEqual(str(rep.to_expression()), "v[1] + v[1] + v[3] + 2*v[4] + 3*v[5]")
+        self.assertEqual(
+            str(rep.to_expression()),
+            "v[1] + p[1]*v[1] + (1 + p[2])*v[2] + (1 + p[3])*v[3] + (1 + p[4])*v[4] + (1 + p[5])*v[5]",
+        )
 
     def test_linear2(self):
         m = ConcreteModel()