Update Amounts and Units for better sorting and filtering behavior#6994
Update Amounts and Units for better sorting and filtering behavior#6994
Conversation
(just working here, not for 24.11)
…s conversion more consistent in a bunch of places. ColumnRenderProperties.getConvertFn()
…fields to base units
# Conflicts: # api/src/org/labkey/api/data/ColumnRenderPropertiesImpl.java # api/src/org/labkey/api/data/DataColumn.java # api/src/org/labkey/api/data/DisplayColumn.java # api/src/org/labkey/api/ontology/KindOfQuantity.java # api/src/org/labkey/api/ontology/Quantity.java # api/src/org/labkey/api/ontology/Unit.java # experiment/resources/schemas/dbscripts/postgresql/exp-25.005-25.006.sql # experiment/resources/schemas/dbscripts/sqlserver/exp-25.005-25.006.sql
…he prepared statement anyway.
…mount display column default
Add "Stored Amount" as an import alias for StoredAmount column Add and use ImportAliasable.Helper.createImportMap() for SampleTypeUpdateServiceDI to get StoredAmount and Units column index
…unt and RawUnits when selecting from exp.material on update from file
… into fb_amountsAndUnits
…tries after upgrade
| public class ExperimentWarningProvider implements WarningProvider | ||
| { | ||
| @Override | ||
| public void addDynamicWarnings(@NotNull Warnings warnings, @Nullable ViewContext context, boolean showAllWarnings) |
There was a problem hiding this comment.
I believe we'll call this method on every LKS page load for admins, so we should cache the message to avoid requerying (likely very large) audit table when there is a mismatch.
There was a problem hiding this comment.
One idea is to store an additional ExperimentModule.ACTUAL_AUDIT_COUNT_PROP in ExperimentModule.AMOUNT_AND_UNIT_UPGRADE_PROP property map.
There was a problem hiding this comment.
Storing the count as a class member seems to work.
experiment/src/org/labkey/experiment/ExperimentWarningProvider.java
Outdated
Show resolved
Hide resolved
| if (rawUnits == null) | ||
| return null; | ||
| if (rawUnits instanceof Unit u) | ||
| if (defaultUnits == null) |
There was a problem hiding this comment.
Can we add the outer braces to the block of if/else if/else ? It's confusing to read and error prone.
| public class ExperimentWarningProvider implements WarningProvider | ||
| { | ||
| @Override | ||
| public void addDynamicWarnings(@NotNull Warnings warnings, @Nullable ViewContext context, boolean showAllWarnings) |
There was a problem hiding this comment.
One idea is to store an additional ExperimentModule.ACTUAL_AUDIT_COUNT_PROP in ExperimentModule.AMOUNT_AND_UNIT_UPGRADE_PROP property map.
| else if (materialUnit != null && !materialUnit.isCompatible(baseUnit)) | ||
| { | ||
| LOG.info("{} '{}' for sample '{}' is not compatible with the base unit '{}'. No conversion done.", isAliquot ? "Aliquot unit" : "Unit", materialUnit.name(), sampleMap.get(Name.name()), baseUnit); | ||
| sampleCounts.put("invalidUnits", sampleCounts.getOrDefault("invalidUnits", 0) + 1); |
There was a problem hiding this comment.
Is it time to change those log level to DEBUG?
| { | ||
| PropertyManager.WritablePropertyMap props = PropertyManager.getWritableProperties(AMOUNT_AND_UNIT_UPGRADE_PROP, true); | ||
| props.put(AUDIT_COUNT_PROP, auditCount.toString()); | ||
| props.put(TRANSACTION_ID_PROP, transactionId == null ? null : transactionId.toString()); |
There was a problem hiding this comment.
If transactionId is null, do we still want to set property map?
There was a problem hiding this comment.
It can't really be null unless my read of the logic is incorrect. This null check just to appease the IntelliJ warnings.
| } | ||
|
|
||
| if (!StringUtils.isEmpty(totalDisplayUnitStr)) | ||
| Unit totalUnit = null; |
There was a problem hiding this comment.
I feel we are not taking advantage of the fact now all aliquots are now stored in the same base "units", if sample type has a unit set. Rollup should now be much simpler (and faster) for sample types with unit, potentially could be done with a simple sql script.
There was a problem hiding this comment.
Yeah, I see what you're saying, but I'm going to not make this change now. We can make this optimization in a separate, smaller PR so we can concentrate on assuring no regressions with the rollup vs. the unit conversion code.
There was a problem hiding this comment.
Can you open an issue for this so we don't forget?
There was a problem hiding this comment.
Rationale
Our original implementation for the StoredAmount and Units columns added display columns over the user-provided data so the application grid displays used consistent units, but left the values as provided by users. Since we accept values in different, compatible units, this results in sorting and filtering on these columns not behaving as one would expect (e.g, samples with amounts of 2 mL and 2 L will be sorted next to each other, though displayed as 2 mL and 2000 mL in the grid).
This work update our handling of
StoredAmountandUnitsso they always store values in the base units for sample types that have display units. This provides us with a valid basis for sorting and filtering.We also are updating the processing of data to always require that the user provides both StoredAmount and Units when either of these values is provided.
Related Pull Requests
Changes
Measurementclass in favor ofQuantityandUnitsclassesSampleTypeAmountDisplayColumnandSampleTyepUnitDisplayColumnto display amount and units using chosen display units