diff --git a/ehr/src/org/labkey/ehr/query/EHRLookupsUserSchema.java b/ehr/src/org/labkey/ehr/query/EHRLookupsUserSchema.java index 26ca6a40d..7f948d598 100644 --- a/ehr/src/org/labkey/ehr/query/EHRLookupsUserSchema.java +++ b/ehr/src/org/labkey/ehr/query/EHRLookupsUserSchema.java @@ -212,10 +212,20 @@ else if (EHRSchema.TABLE_LOOKUP_SETS.equalsIgnoreCase(name)) // By default, any hard tables in the ehr_lookups schema not accounted for above will fall into one of the // two categories below. Both of these will add a check that makes sure the user has EHRDataAdminPermission - // in order to insert/update/delete on the table. The ContainerScopedTable case is for those tables that - // have a true DB PK or rowid but a User pseudoPK that should be accounted for at the container level. + // in order to insert/update/delete on the table. The ContainerScopedTable case is for tables whose + // user-facing key (promoted via isKeyField in ehr_lookups.xml) differs from the true DB PK: the PK + // constraint does not enforce uniqueness of the pseudo-PK, so the wrapper enforces it per container and + // resolves the pseudo-PK to the real PK on update. Tables whose user-facing key is the true PK + // (e.g. project_types) get CustomPermissionsTable instead: the PK constraint already enforces uniqueness, + // and container-scoping such a table made its key column non-insertable in the UI. String pkColName = getPkColName(ti); - if (pkColName != null && !"rowid".equalsIgnoreCase(pkColName) && ti.getColumn("container") != null) + List realPk = ti instanceof FilteredTable ft + ? ft.getRealTable().getPkColumnNames() + : _dbSchema.getTable(name).getPkColumnNames(); + boolean singleColumnPks = pkColName != null && realPk.size() == 1; + boolean realPkMatchesPseudoPk = singleColumnPks && realPk.get(0).equalsIgnoreCase(pkColName); + + if (singleColumnPks && !realPkMatchesPseudoPk && ti.getColumn("container") != null) return getContainerScopedTable(name, cf, pkColName, EHRDataAdminPermission.class); else return getCustomPermissionTable(createSourceTable(name), cf, EHRDataAdminPermission.class); diff --git a/ehr_billing/src/org/labkey/ehr_billing/notification/BillingNotification.java b/ehr_billing/src/org/labkey/ehr_billing/notification/BillingNotification.java index aa8c244b0..8c7c01262 100644 --- a/ehr_billing/src/org/labkey/ehr_billing/notification/BillingNotification.java +++ b/ehr_billing/src/org/labkey/ehr_billing/notification/BillingNotification.java @@ -464,8 +464,8 @@ protected void createChargeSummaryReport(final StringBuilder msg, Date lastInvoi String baseUrl = createURL(containerMap.get(category), centerSpecificBillingSchema, categoryToQuery.get(category), null) + "&query.param.StartDate=" + getDateFormat(c).format(start.getTime()) + "&query.param.EndDate=" + getDateFormat(c).format(endDate.getTime()); String projUrl = baseUrl + ("None".equals(tokens[1]) ? "&query.project~isblank" : "&query.project~eq=" + tokens[1]); - msg.append("" + financialAnalyst + ""); //the FA - msg.append("" + tokens[1] + ""); + msg.append("" + PageFlowUtil.filter(financialAnalyst) + ""); //the FA + msg.append("" + PageFlowUtil.filter(tokens[1]) + ""); String accountUrl = null; Container financeContainer = EHR_BillingManager.get().getBillingContainer(containerMap.get(category)); @@ -476,22 +476,22 @@ protected void createChargeSummaryReport(final StringBuilder msg, Date lastInvoi if (accountUrl != null) { - msg.append("" + tokens[2] + ""); + msg.append("" + PageFlowUtil.filter(tokens[2]) + ""); } else { - msg.append("" + (tokens[2]) + ""); + msg.append("" + PageFlowUtil.filter(tokens[2]) + ""); } - msg.append("" + (tokens[3]) + ""); - msg.append("" + category + ""); + msg.append("" + PageFlowUtil.filter(tokens[3]) + ""); + msg.append("" + PageFlowUtil.filter(category) + ""); for (FieldDescriptor fd : foundCols) { if (totals.containsKey(fd.getFieldName())) { String url = projUrl + fd.getFilter(); - msg.append("" + totals.get(fd.getFieldName()) + ""); + msg.append("" + totals.get(fd.getFieldName()) + ""); } else {