From 705c517acf38da136afa757d6c6788209b601f43 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Tue, 9 Dec 2025 02:11:43 +0000 Subject: [PATCH] Added totalTime field to Job and SubJob models for duration calculation, and updated OrderItem model to include reference field and reorder properties for improved data structure. --- src/database/models/Job.js | 33 ++++++++++++++++++-- src/database/models/OrderItem.js | 21 +++++++++---- src/database/models/SubJob.js | 52 +++++++++++++++++++++----------- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/database/models/Job.js b/src/database/models/Job.js index e49bb2b..1d2260d 100644 --- a/src/database/models/Job.js +++ b/src/database/models/Job.js @@ -2,6 +2,7 @@ import JobIcon from '../../components/Icons/JobIcon' import InfoCircleIcon from '../../components/Icons/InfoCircleIcon' import ReloadIcon from '../../components/Icons/ReloadIcon' import CheckIcon from '../../components/Icons/CheckIcon' +import dayjs from 'dayjs' export const Job = { name: 'job', @@ -37,7 +38,7 @@ export const Job = { url: (_id) => `/dashboard/production/jobs/info?jobId=${_id}&action=reload` } ], - columns: ['_id', 'gcodeFile', 'quantity', 'state', 'createdAt'], + columns: ['_id', 'quantity', 'state', 'gcodeFile', 'createdAt'], filters: ['state', '_id', 'gcodeFile', 'quantity'], sorters: ['createdAt', 'state', 'quantity', 'gcodeFile'], properties: [ @@ -77,6 +78,7 @@ export const Job = { name: 'quantity', label: 'Quantity', type: 'number', + columnFixed: 'left', columnWidth: 125, required: true }, @@ -103,10 +105,37 @@ export const Job = { name: 'gcodeFile', label: 'GCode File', type: 'object', - columnFixed: 'left', + objectType: 'gcodeFile', required: true, showHyperlink: true + }, + { + name: 'totalTime', + label: 'Total Time', + type: 'text', + readOnly: true, + value: (objectData) => { + if (!objectData?.startedAt || !objectData?.finishedAt) { + return '-' + } + const totalSeconds = dayjs(objectData?.finishedAt).diff( + dayjs(objectData?.startedAt), + 'seconds' + ) + const days = Math.floor(totalSeconds / 86400) + const hours = Math.floor((totalSeconds % 86400) / 3600) + const minutes = Math.floor((totalSeconds % 3600) / 60) + const seconds = totalSeconds % 60 + + const parts = [] + if (days > 0) parts.push(`${days}d`) + if (hours > 0) parts.push(`${hours}h`) + if (minutes > 0) parts.push(`${minutes}m`) + if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`) + + return parts.join(' ') + } } ], stats: [ diff --git a/src/database/models/OrderItem.js b/src/database/models/OrderItem.js index 70f0123..480b122 100644 --- a/src/database/models/OrderItem.js +++ b/src/database/models/OrderItem.js @@ -49,13 +49,13 @@ export const OrderItem = { type: 'dateTime', readOnly: true }, - { - name: 'orderType', - label: 'Order Type', - type: 'objectType', - masterFilter: ['purchaseOrder', 'salesOrder'], - required: true + name: '_reference', + label: 'Reference', + type: 'reference', + objectType: 'orderItem', + showCopy: true, + readOnly: true }, { name: 'updatedAt', @@ -63,6 +63,15 @@ export const OrderItem = { type: 'dateTime', readOnly: true }, + { name: 'state', label: 'State', type: 'state', readOnly: true }, + { + name: 'orderType', + label: 'Order Type', + type: 'objectType', + masterFilter: ['purchaseOrder', 'salesOrder'], + required: true + }, + { name: 'order', label: 'Order', diff --git a/src/database/models/SubJob.js b/src/database/models/SubJob.js index 9eec9fc..8bf9f1d 100644 --- a/src/database/models/SubJob.js +++ b/src/database/models/SubJob.js @@ -1,6 +1,7 @@ import SubJobIcon from '../../components/Icons/SubJobIcon' import InfoCircleIcon from '../../components/Icons/InfoCircleIcon' import XMarkIcon from '../../components/Icons/XMarkIcon' +import dayjs from 'dayjs' export const SubJob = { name: 'subJob', @@ -68,7 +69,6 @@ export const SubJob = { readOnly: true, columnWidth: 175 }, - { name: 'moonrakerJobId', label: 'Moonraker Job ID', @@ -76,28 +76,12 @@ export const SubJob = { columnWidth: 140, showCopy: true }, - { name: 'startedAt', label: 'Started At', type: 'dateTime', readOnly: true }, - - { - name: 'createdPartStock', - label: 'Created Part Stock', - type: 'bool', - readOnly: true - }, - - { - name: 'finishedAt', - label: 'Finished At', - type: 'dateTime', - readOnly: true - }, - { name: 'job', label: 'Job', @@ -105,7 +89,12 @@ export const SubJob = { objectType: 'job', showHyperlink: true }, - + { + name: 'finishedAt', + label: 'Finished At', + type: 'dateTime', + readOnly: true + }, { name: 'printer', label: 'Printer', @@ -113,6 +102,33 @@ export const SubJob = { columnFixed: 'left', objectType: 'printer', showHyperlink: true + }, + { + name: 'totalTime', + label: 'Total Time', + type: 'text', + readOnly: true, + value: (objectData) => { + if (!objectData?.startedAt || !objectData?.finishedAt) { + return '-' + } + const totalSeconds = dayjs(objectData?.finishedAt).diff( + dayjs(objectData?.startedAt), + 'seconds' + ) + const days = Math.floor(totalSeconds / 86400) + const hours = Math.floor((totalSeconds % 86400) / 3600) + const minutes = Math.floor((totalSeconds % 3600) / 60) + const seconds = totalSeconds % 60 + + const parts = [] + if (days > 0) parts.push(`${days}d`) + if (hours > 0) parts.push(`${hours}h`) + if (minutes > 0) parts.push(`${minutes}m`) + if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`) + + return parts.join(' ') + } } ] }