mirror of
https://github.com/inventree/InvenTree.git
synced 2026-08-10 15:36:17 +00:00
Fix test result ordering by test timestamps (#12533)
* Fix test result ordering by test timestamps * Refractor test result comparison helper * Apply formatting fixes * Fix frontend formatting * Avoid mutating test result records * Add migration for test result ordering * Retry documentation build --------- Co-authored-by: jayasree723 <confidentlehmann@tomorjerry.com> Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
co-authored by
jayasree723
Oliver
parent
afcc89ecfb
commit
214f472ec9
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.2.16
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("stock", "0126_serial_number_concurrency_guard"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="stockitemtestresult",
|
||||
options={
|
||||
"ordering": (
|
||||
"-finished_datetime",
|
||||
"-started_datetime",
|
||||
"-date",
|
||||
"-pk",
|
||||
),
|
||||
"verbose_name": "Stock Item Test Result",
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -3820,6 +3820,8 @@ class StockItemTestResult(InvenTree.models.InvenTreeMetadataModel):
|
||||
|
||||
verbose_name = _('Stock Item Test Result')
|
||||
|
||||
ordering = ('-finished_datetime', '-started_datetime', '-date', '-pk')
|
||||
|
||||
def __str__(self):
|
||||
"""Return string representation."""
|
||||
return f'{self.test_name} - {self.result}'
|
||||
|
||||
@@ -53,3 +53,42 @@ export function isEquivalent(a: any, b: any): boolean {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function compareTestResults(a: any, b: any) {
|
||||
const finishedA = a.finished_datetime
|
||||
? new Date(a.finished_datetime).getTime()
|
||||
: null;
|
||||
const finishedB = b.finished_datetime
|
||||
? new Date(b.finished_datetime).getTime()
|
||||
: null;
|
||||
|
||||
if (finishedA !== finishedB) {
|
||||
if (finishedA === null) return 1;
|
||||
if (finishedB === null) return -1;
|
||||
return finishedB - finishedA;
|
||||
}
|
||||
|
||||
const startedA = a.started_datetime
|
||||
? new Date(a.started_datetime).getTime()
|
||||
: null;
|
||||
const startedB = b.started_datetime
|
||||
? new Date(b.started_datetime).getTime()
|
||||
: null;
|
||||
|
||||
if (startedA !== startedB) {
|
||||
if (startedA === null) return 1;
|
||||
if (startedB === null) return -1;
|
||||
return startedB - startedA;
|
||||
}
|
||||
|
||||
const uploadTimeA = a.date ? new Date(a.date).getTime() : null;
|
||||
const uploadTimeB = b.date ? new Date(b.date).getTime() : null;
|
||||
|
||||
if (uploadTimeA !== uploadTimeB) {
|
||||
if (uploadTimeA === null) return 1;
|
||||
if (uploadTimeB === null) return -1;
|
||||
return uploadTimeB - uploadTimeA;
|
||||
}
|
||||
|
||||
return b.pk - a.pk;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ import {
|
||||
useStockFields,
|
||||
useStockItemSerializeFields
|
||||
} from '../../forms/StockForms';
|
||||
import { compareTestResults } from '../../functions/comparison';
|
||||
import { InvenTreeIcon } from '../../functions/icons';
|
||||
import useBackgroundTask from '../../hooks/UseBackgroundTask';
|
||||
import {
|
||||
@@ -277,9 +278,7 @@ export default function BuildOutputTable({
|
||||
// Find the "newest" result for this template in the returned data
|
||||
const result = record.tests
|
||||
?.filter((test: any) => test.template == template.pk)
|
||||
.sort((a: any, b: any) => {
|
||||
return a.pk < b.pk ? 1 : -1;
|
||||
})
|
||||
.sort(compareTestResults)
|
||||
.shift();
|
||||
|
||||
if (template?.required && result?.result) {
|
||||
|
||||
@@ -37,6 +37,7 @@ import RowExpansionIcon from '../../components/tables/RowExpansionIcon';
|
||||
import { useApi } from '../../contexts/ApiContext';
|
||||
import { formatDate } from '../../defaults/formatters';
|
||||
import { useTestResultFields } from '../../forms/StockForms';
|
||||
import { compareTestResults } from '../../functions/comparison';
|
||||
import {
|
||||
useCreateApiFormModal,
|
||||
useDeleteApiFormModal,
|
||||
@@ -110,13 +111,9 @@ export default function StockItemTestResultTable({
|
||||
});
|
||||
|
||||
// Iterate through the returned records
|
||||
// Note that the results are sorted by oldest first,
|
||||
// to ensure that the most recent result is displayed "on top"
|
||||
records
|
||||
.sort((a: any, b: any) => {
|
||||
return a.pk > b.pk ? 1 : -1;
|
||||
})
|
||||
.forEach((record) => {
|
||||
// Sort test results using the same priority as the backend:
|
||||
// finished_datetime -> started_datetime -> date -> pk
|
||||
records.toSorted(compareTestResults).forEach((record) => {
|
||||
// Find matching template
|
||||
const idx = results.findIndex(
|
||||
(r: any) => r.templateId == record.template
|
||||
|
||||
Reference in New Issue
Block a user