Add OrderItem and Shipment models to database schema

- Introduced OrderItem and Shipment models with associated properties and actions.
- Updated ObjectModels to include new models for better integration.
- Refactored existing models to remove unnecessary ID references and improve hyperlink support for related objects.
- Enhanced various models by removing deprecated fields and ensuring consistency in object references.
This commit is contained in:
Tom Butcher 2025-12-07 02:41:17 +00:00
parent 2f323181f5
commit f24bc27e2c
21 changed files with 605 additions and 582 deletions

View File

@ -18,6 +18,8 @@ import { StockAudit } from './models/StockAudit'
import { PartStock } from './models/PartStock'
import { ProductStock } from './models/ProductStock'
import { PurchaseOrder } from './models/PurchaseOrder'
import { OrderItem } from './models/OrderItem'
import { Shipment } from './models/Shipment'
import { AuditLog } from './models/AuditLog'
import { User } from './models/User'
import { NoteType } from './models/NoteType'
@ -51,6 +53,8 @@ export const objectModels = [
PartStock,
ProductStock,
PurchaseOrder,
OrderItem,
Shipment,
AuditLog,
User,
NoteType,
@ -85,6 +89,8 @@ export {
PartStock,
ProductStock,
PurchaseOrder,
OrderItem,
Shipment,
AuditLog,
User,
NoteType,

View File

@ -9,13 +9,12 @@ export const AuditLog = {
columns: [
'_id',
'owner',
'owner._id',
'parent._id',
'parent',
'operation',
'changes',
'createdAt'
],
filters: ['_id', 'owner._id', 'parent._id', 'operation'],
filters: ['_id', 'owner', 'parent', 'operation'],
sorters: ['createdAt'],
properties: [
{
@ -50,18 +49,8 @@ export const AuditLog = {
},
columnFixed: 'left',
value: null,
showCopy: true
},
{
name: 'owner._id',
label: 'Owner ID',
type: 'id',
objectType: (objectData) => {
return objectData.ownerType
},
columnFixed: 'left',
showHyperlink: true,
showCopy: true
showCopy: true,
showHyperlink: true
},
{
name: 'parent',
@ -71,17 +60,8 @@ export const AuditLog = {
return objectData.parentType
},
value: null,
showCopy: true
},
{
name: 'parent._id',
label: 'Parent ID',
type: 'id',
objectType: (objectData) => {
return objectData.parentType
},
showHyperlink: true,
showCopy: true
showCopy: true,
showHyperlink: true
},
{
name: 'operation',

View File

@ -74,15 +74,14 @@ export const CourierService = {
'name',
'_id',
'courier',
'courier._id',
'tracked',
'deliveryTime',
'active'
],
filters: ['name', '_id', 'courier._id', 'active', 'deliveryTime', 'tracked'],
filters: ['name', '_id', 'courier', 'active', 'deliveryTime', 'tracked'],
sorters: [
'name',
'courier._id',
'courier',
'active',
'tracked',
'estimatedDeliveryTime',
@ -126,13 +125,6 @@ export const CourierService = {
showHyperlink: true,
required: true
},
{
name: 'courier._id',
label: 'Courier ID',
type: 'id',
objectType: 'courier',
showHyperlink: true
},
{
name: 'deliveryTime',
label: 'Delivery Time',

View File

@ -121,16 +121,8 @@ export const DocumentJob = {
type: 'object',
objectType: (objectData) => {
return objectData?.objectType
}
},
{
name: 'object._id',
label: 'Object ID',
type: 'id',
showHyperlink: true,
objectType: (objectData) => {
return objectData?.objectType
}
showHyperlink: true
},
{
name: 'documentTemplate',
@ -139,6 +131,7 @@ export const DocumentJob = {
columnWidth: 150,
type: 'object',
objectType: 'documentTemplate',
showHyperlink: true,
masterFilter: (objectData) => {
return {
active: true,
@ -147,13 +140,6 @@ export const DocumentJob = {
}
}
},
{
name: 'documentTemplate._id',
label: 'Template ID',
type: 'id',
showHyperlink: true,
objectType: 'documentTemplate'
},
{
name: 'documentPrinter',
label: 'Printer',
@ -161,19 +147,13 @@ export const DocumentJob = {
columnWidth: 150,
type: 'object',
objectType: 'documentPrinter',
showHyperlink: true,
masterFilter: () => {
return {
active: true,
online: true
}
}
},
{
name: 'documentPrinter._id',
label: 'Printer ID',
type: 'id',
showHyperlink: true,
objectType: 'documentPrinter'
}
]
}

View File

@ -66,7 +66,6 @@ export const DocumentPrinter = {
'_id',
'state',
'host',
'host._id',
'tags',
'connectedAt',
'updatedAt'
@ -132,15 +131,8 @@ export const DocumentPrinter = {
label: 'Vendor',
type: 'object',
objectType: 'vendor',
required: false
},
{
name: 'vendor._id',
label: 'Vendor ID',
type: 'id',
objectType: 'vendor',
showHyperlink: true,
readOnly: true
required: false,
showHyperlink: true
},
{
name: 'host',
@ -150,14 +142,6 @@ export const DocumentPrinter = {
objectType: 'host',
showHyperlink: true
},
{
name: 'host._id',
label: 'Host ID',
type: 'id',
objectType: 'host',
showCopy: true,
showHyperlink: true
},
{
name: 'connection.interface',
label: 'Interface',
@ -211,14 +195,7 @@ export const DocumentPrinter = {
label: 'Current Document Size',
required: false,
type: 'object',
objectType: 'documentSize'
},
{
name: 'currentDocumentSize._id',
label: 'Current Document Size ID',
type: 'id',
objectType: 'documentSize',
showCopy: true,
showHyperlink: true
},
{

View File

@ -78,9 +78,7 @@ export const DocumentTemplate = {
'objectType',
'tags',
'parent',
'parent._id',
'documentSize',
'documentSize._id',
'createdAt',
'updatedAt'
],
@ -158,14 +156,7 @@ export const DocumentTemplate = {
label: 'Document Size',
required: true,
type: 'object',
objectType: 'documentSize'
},
{
name: 'documentSize._id',
label: 'Document Size ID',
type: 'id',
objectType: 'documentSize',
showCopy: true,
showHyperlink: true
},
{
@ -175,17 +166,7 @@ export const DocumentTemplate = {
type: 'object',
masterFilter: { global: true, active: true },
objectType: 'documentTemplate',
empty: (documentTemplate) => {
return documentTemplate.global
}
},
{
name: 'parent._id',
label: 'Parent ID',
required: false,
type: 'id',
showHyperlink: true,
objectType: 'documentTemplate',
empty: (documentTemplate) => {
return documentTemplate.global
}

View File

@ -65,14 +65,13 @@ export const Filament = {
'type',
'color',
'vendor',
'vendor._id',
'cost',
'density',
'diameter',
'createdAt',
'updatedAt'
],
filters: ['_id', 'name', 'type', 'color', 'cost', 'vendor', 'vendor._id'],
filters: ['_id', 'name', 'type', 'color', 'cost', 'vendor'],
sorters: [
'name',
'createdAt',
@ -116,14 +115,7 @@ export const Filament = {
label: 'Vendor',
required: true,
type: 'object',
objectType: 'vendor'
},
{
name: 'vendor._id',
label: 'Vendor ID',
type: 'id',
objectType: 'vendor',
showCopy: true,
showHyperlink: true
},
{

View File

@ -23,7 +23,6 @@ export const FilamentStock = {
'currentWeight',
'startingWeight',
'filament',
'filament._id',
'createdAt',
'updatedAt'
],
@ -65,15 +64,8 @@ export const FilamentStock = {
objectType: 'filament',
readOnly: true,
initial: true,
required: true
},
{
name: 'filament._id',
label: 'Filament ID',
type: 'id',
objectType: 'filament',
showHyperlink: true,
readOnly: true
required: true,
showHyperlink: true
},
{
name: 'currentWeight',

View File

@ -122,31 +122,16 @@ export const GCodeFile = {
value: null,
required: true,
showPreview: false,
showHyperlink: false,
showHyperlink: true,
filter: ['.gcode', '.g']
},
{
name: 'file._id',
label: 'File ID',
type: 'id',
value: null,
objectType: 'file',
showHyperlink: true
},
{
name: 'filament',
label: 'Filament',
type: 'object',
value: null,
objectType: 'filament',
required: true
},
{
name: 'filament._id',
label: 'Filament ID',
type: 'id',
value: null,
objectType: 'filament',
required: true,
showHyperlink: true
},
{
@ -236,17 +221,8 @@ export const GCodeFile = {
label: 'Part',
type: 'object',
objectType: 'part',
required: true
},
{
name: 'part._id',
label: 'Part ID',
type: 'id',
objectType: 'part',
showHyperlink: true,
value: (objectData) => {
return objectData?.part?._id
}
required: true,
showHyperlink: true
},
{
name: 'quantity',

View File

@ -40,13 +40,12 @@ export const Job = {
columns: [
'_id',
'gcodeFile',
'gcodeFile._id',
'quantity',
'state',
'createdAt'
],
filters: ['state', '_id', 'gcodeFile._id', 'quantity'],
filters: ['state', '_id', 'gcodeFile', 'quantity'],
sorters: ['createdAt', 'state', 'quantity', 'gcodeFile'],
properties: [
{
@ -113,13 +112,7 @@ export const Job = {
type: 'object',
columnFixed: 'left',
objectType: 'gcodeFile',
required: true
},
{
name: 'gcodeFile._id',
label: 'GCode File ID',
type: 'id',
objectType: 'gcodeFile',
required: true,
showHyperlink: true
}
]

View File

@ -31,9 +31,30 @@ export const Note = {
readOnly: true
},
{
name: 'parent._id',
label: 'Parent ID',
type: 'id',
name: '_reference',
label: 'Reference',
type: 'reference',
objectType: 'note',
showCopy: true,
readOnly: true
},
{
name: 'updatedAt',
label: 'Updated At',
type: 'dateTime',
readOnly: true
},
{
name: 'user',
label: 'User',
type: 'object',
objectType: 'user',
showHyperlink: true
},
{
name: 'parent',
label: 'Parent',
type: 'object',
objectType: (objectData) => {
return objectData.parentType
},
@ -54,24 +75,6 @@ export const Note = {
objectType: 'noteType',
showHyperlink: true,
required: true
},
{
name: 'noteType._id',
label: 'Note Type ID',
type: 'id',
objectType: 'noteType'
},
{
name: 'user._id',
label: 'User ID',
type: 'id',
objectType: 'user'
},
{
name: 'updatedAt',
label: 'Updated At',
type: 'dateTime',
readOnly: true
}
]
}

View File

@ -0,0 +1,214 @@
import OrderItemIcon from '../../components/Icons/OrderItemIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
export const OrderItem = {
name: 'orderItem',
label: 'Order Item',
prefix: 'ODI',
icon: OrderItemIcon,
actions: [
{
name: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon,
url: (_id) => `/dashboard/inventory/orderitems/info?orderItemId=${_id}`
}
],
group: [],
filters: ['itemType', 'item', 'order'],
sorters: ['createdAt', 'updatedAt', 'itemAmount', 'quantity'],
columns: [
'_id',
'itemType',
'item',
'itemAmount',
'quantity',
'totalAmount',
'taxRate',
'totalAmountWithTax',
'order',
'createdAt',
'updatedAt'
],
properties: [
{
name: '_id',
label: 'ID',
type: 'id',
columnFixed: 'left',
objectType: 'orderItem',
columnWidth: 140,
showCopy: true
},
{
name: 'createdAt',
label: 'Created At',
type: 'dateTime',
readOnly: true
},
{
name: 'orderType',
label: 'Order Type',
type: 'objectType',
masterFilter: ['purchaseOrder', 'salesOrder'],
required: true
},
{
name: 'updatedAt',
label: 'Updated At',
type: 'dateTime',
readOnly: true
},
{
name: 'order',
label: 'Order',
type: 'object',
showHyperlink: true,
objectType: (objectData) => {
return objectData?.orderType
},
required: true
},
{
name: 'itemType',
label: 'Item Type',
type: 'objectType',
masterFilter: ['part', 'packaging'],
required: true,
columnWidth: 125
},
{
name: 'item',
label: 'Item',
type: 'object',
objectType: (objectData) => {
return objectData?.itemType
},
required: true,
showHyperlink: true,
columnWidth: 300
},
{
name: 'syncAmount',
label: 'Sync Amount',
type: 'select',
options: [
{ label: 'Item Cost', value: 'itemCost' },
{ label: 'Item Price', value: 'itemPrice' },
{ label: 'None', value: null }
],
required: false
},
{
name: 'itemAmount',
label: 'Item Amount',
type: 'number',
required: true,
prefix: '£',
min: 0,
step: 0.01,
readOnly: (objectData) => {
return objectData?.syncAmount != null
},
columnWidth: 150,
value: (objectData) => {
if (objectData?.item?.cost && objectData?.syncAmount == 'itemCost') {
return objectData?.item?.cost || undefined
}
if (objectData?.item?.price && objectData?.syncAmount == 'itemPrice') {
return objectData?.item?.price || undefined
}
return objectData?.itemAmount || undefined
}
},
{
name: 'quantity',
label: 'Quantity',
type: 'number',
required: true,
columnWidth: 150
},
{
name: 'totalAmount',
label: 'Total Amount',
type: 'number',
required: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 150,
readOnly: true,
value: (objectData) => {
if (objectData?.itemAmount && objectData?.quantity) {
return (
(objectData?.itemAmount || 0) * (objectData?.quantity || 0)
).toFixed(2)
} else {
return 0
}
}
},
{
name: 'taxRate',
label: 'Tax Rate',
type: 'object',
objectType: 'taxRate',
showHyperlink: true,
value: (objectData) => {
if (
objectData?.item?.costTaxRate?._id &&
objectData?.syncAmount == 'itemCost'
) {
return objectData?.item?.costTaxRate || undefined
} else if (
objectData?.item?.priceTaxRate?._id &&
objectData?.syncAmount == 'itemPrice'
) {
return objectData?.item?.priceTaxRate || undefined
} else {
return objectData?.taxRate || undefined
}
},
readOnly: (objectData) => {
return objectData?.syncAmount != null
}
},
{
name: 'totalAmountWithTax',
label: 'Total Amount w/ Tax',
type: 'number',
required: true,
readOnly: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 175,
value: (objectData) => {
const totalAmount = objectData?.itemAmount * objectData?.quantity || 0
if (objectData?.taxRate?.rateType == 'percentage') {
if (objectData?.quantity == undefined || objectData?.quantity == 0) {
return undefined
}
return (
(
(totalAmount || 0) *
(1 + objectData?.taxRate?.rate / 100)
).toFixed(2) || undefined
)
} else if (objectData?.taxRate?.rateType == 'amount') {
return (
((totalAmount || 0) + objectData?.taxRate?.rate).toFixed(2) ||
undefined
)
} else {
return totalAmount || 0
}
}
}
]
}

View File

@ -58,15 +58,8 @@ export const Part = {
}
}
],
columns: [
'name',
'_id',
'product',
'product._id',
'globalPricing',
'createdAt'
],
filters: ['name', '_id', 'product', 'product._id', 'globalPricing'],
columns: ['name', '_id', 'product', 'globalPricing', 'createdAt'],
filters: ['name', '_id', 'product', 'globalPricing'],
sorters: ['name', 'email', 'role', 'createdAt', '_id'],
properties: [
{
@ -103,6 +96,7 @@ export const Part = {
required: true,
type: 'object',
objectType: 'vendor',
showHyperlink: true,
value: (objectData) => {
console.log(objectData?.vendor, objectData?.product?.vendor)
if (!objectData?.vendor && objectData?.product?.vendor) {
@ -112,14 +106,6 @@ export const Part = {
}
}
},
{
name: 'vendor._id',
label: 'Vendor ID',
readOnly: true,
type: 'id',
showHyperlink: true,
objectType: 'vendor'
},
{
name: 'cost',
label: 'Cost',
@ -132,7 +118,7 @@ export const Part = {
},
{
name: 'costWithTax',
label: 'Cost with Tax',
label: 'Cost w/ Tax',
columnWidth: 150,
required: true,
readOnly: true,
@ -163,15 +149,8 @@ export const Part = {
label: 'Cost Tax Rate',
required: true,
type: 'object',
objectType: 'taxRate'
},
{
name: 'costTaxRate._id',
label: 'Cost Tax Rate ID',
readOnly: true,
type: 'id',
showHyperlink: true,
objectType: 'taxRate'
objectType: 'taxRate',
showHyperlink: true
},
{
name: 'price',
@ -201,7 +180,7 @@ export const Part = {
},
{
name: 'priceWithTax',
label: 'Price with Tax',
label: 'Price w/ Tax',
columnWidth: 150,
required: true,
readOnly: true,
@ -251,15 +230,8 @@ export const Part = {
label: 'Price Tax Rate',
required: true,
type: 'object',
objectType: 'taxRate'
},
{
name: 'priceTaxRate._id',
label: 'Price Tax Rate ID',
readOnly: true,
type: 'id',
showHyperlink: true,
objectType: 'taxRate'
objectType: 'taxRate',
showHyperlink: true
},
{
@ -267,14 +239,7 @@ export const Part = {
label: 'File',
type: 'file',
value: null,
required: false
},
{
name: 'file._id',
label: 'File ID',
type: 'id',
value: null,
objectType: 'file',
required: false,
showHyperlink: true
}
]

View File

@ -25,7 +25,6 @@ export const PartStock = {
'startingQuantity',
'currentQuantity',
'part',
'part._id',
'createdAt',
'updatedAt'
],
@ -66,26 +65,12 @@ export const PartStock = {
required: true,
masterFilter: ['subJob']
},
{
name: 'consumedAt',
label: 'Consumed At',
type: 'dateTime',
readOnly: true
},
{
name: 'part',
label: 'Part',
type: 'object',
objectType: 'part',
required: true
},
{
name: 'part._id',
label: 'Part ID',
type: 'id',
objectType: 'part',
readOnly: true,
required: true,
showHyperlink: true
},
@ -98,17 +83,8 @@ export const PartStock = {
columnWidth: 200,
objectType: (objectData) => {
return objectData?.sourceType
}
},
{
name: 'source._id',
label: 'Source ID',
type: 'id',
readOnly: true,
columnWidth: 200,
objectType: (objectData) => {
return objectData?.sourceType
}
showHyperlink: true
},
{
name: 'currentQuantity',
@ -124,13 +100,6 @@ export const PartStock = {
return objectData.currentQuantity
}
}
},
{
name: 'startingQuantity',
label: 'Starting Quantity',
type: 'number',
columnWidth: 200,
required: true
}
]
}

View File

@ -213,16 +213,7 @@ export const Printer = {
]
}
],
columns: [
'name',
'_id',
'state',
'host',
'host._id',
'tags',
'connectedAt',
'updatedAt'
],
columns: ['name', '_id', 'state', 'host', 'tags', 'connectedAt', 'updatedAt'],
filters: ['name', '_id', 'state', 'tags'],
sorters: ['name', 'state', 'connectedAt'],
group: ['tags'],
@ -286,30 +277,16 @@ export const Printer = {
label: 'Vendor',
type: 'object',
objectType: 'vendor',
required: false
},
{
name: 'vendor._id',
label: 'Vendor ID',
type: 'id',
objectType: 'vendor',
showHyperlink: true,
readOnly: true
required: false,
showHyperlink: true
},
{
name: 'host',
label: 'Host',
type: 'object',
objectType: 'host',
required: true
},
{
name: 'host._id',
label: 'Host ID',
type: 'id',
objectType: 'host',
showHyperlink: true,
readOnly: true
required: true,
showHyperlink: true
},
{
name: 'moonraker.host',
@ -354,45 +331,24 @@ export const Printer = {
label: 'Filament Stock',
type: 'object',
objectType: 'filamentStock',
required: false
},
{
name: 'currentFilamentStock._id',
label: 'Filament Stock ID',
type: 'id',
objectType: 'filamentStock',
showHyperlink: true,
readOnly: true
required: false,
showHyperlink: true
},
{
name: 'currentJob',
label: 'Current Job',
type: 'object',
objectType: 'job',
required: false
},
{
name: 'currentJob._id',
label: 'Current Job ID',
type: 'id',
objectType: 'job',
showHyperlink: true,
readOnly: true
required: false,
showHyperlink: true
},
{
name: 'currentSubJob',
label: 'Current Sub Job',
type: 'object',
objectType: 'subJob',
required: false
},
{
name: 'currentSubJob._id',
label: 'Current Sub Job ID',
type: 'id',
objectType: 'subJob',
showHyperlink: true,
readOnly: true
required: false,
showHyperlink: true
},
{
name: 'alerts',

View File

@ -64,12 +64,11 @@ export const Product = {
'name',
'tags',
'vendor',
'vendor._id',
'price',
'createdAt',
'updatedAt'
],
filters: ['_id', 'name', 'type', 'color', 'cost', 'vendor', 'vendor._id'],
filters: ['_id', 'name', 'type', 'color', 'cost', 'vendor'],
sorters: ['name', 'createdAt', 'type', 'vendor', 'cost', 'updatedAt'],
properties: [
{
@ -103,15 +102,8 @@ export const Product = {
label: 'Vendor',
required: true,
type: 'object',
objectType: 'vendor'
},
{
name: 'vendor._id',
label: 'Vendor ID',
readOnly: true,
type: 'id',
showHyperlink: true,
objectType: 'vendor'
objectType: 'vendor',
showHyperlink: true
},
{
name: 'version',
@ -167,17 +159,8 @@ export const Product = {
label: 'Part',
type: 'object',
objectType: 'part',
required: true
},
{
name: 'part._id',
label: 'Part ID',
type: 'id',
objectType: 'part',
showHyperlink: true,
value: (objectData) => {
return objectData?.part?._id
}
required: true,
showHyperlink: true
},
{
name: 'quantity',

View File

@ -1,5 +1,6 @@
import PurchaseOrderIcon from '../../components/Icons/PurchaseOrderIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import PlusIcon from '../../components/Icons/PlusIcon'
export const PurchaseOrder = {
name: 'purchaseOrder',
@ -15,12 +16,20 @@ export const PurchaseOrder = {
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}`
},
{
name: 'New Order Item',
label: 'New Order Item',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=newOrderItem`
}
],
group: ['vendor'],
filters: ['vendor', 'vendor._id'],
filters: ['vendor'],
sorters: ['createdAt', 'state', 'updatedAt'],
columns: ['_id', 'createdAt', 'state', 'updatedAt', 'vendor', 'vendor._id'],
columns: ['_id', 'createdAt', 'state', 'updatedAt', 'vendor'],
properties: [
{
name: '_id',
@ -49,183 +58,8 @@ export const PurchaseOrder = {
label: 'Vendor',
required: true,
type: 'object',
objectType: 'vendor'
},
{
name: 'vendor._id',
label: 'Vendor ID',
readOnly: true,
type: 'id',
showHyperlink: true,
objectType: 'vendor'
},
{
name: 'items',
label: 'Order Items',
type: 'objectChildren',
required: true,
properties: [
{
name: 'itemType',
label: 'Item Type',
type: 'objectType',
masterFilter: ['part', 'packaging'],
required: true
},
{
name: 'item',
label: 'Item',
type: 'object',
objectType: (objectData) => {
return objectData?.itemType
},
required: true
},
{
name: 'item._id',
label: 'Item ID',
type: 'id',
objectType: (objectData) => {
return objectData?.itemType
},
showHyperlink: true,
value: (objectData) => {
return objectData?.item?._id
}
},
{
name: 'itemCost',
label: 'Item Cost',
type: 'number',
required: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 150,
value: (objectData) => {
if (objectData?.item) {
return objectData?.item?.cost || undefined
} else {
return undefined
}
}
},
{
name: 'quantity',
label: 'Quantity',
type: 'number',
required: true,
columnWidth: 150
},
{
name: 'totalCost',
label: 'Total Cost',
type: 'number',
required: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 150,
value: (objectData) => {
return (
(objectData?.itemCost || 0) * (objectData?.quantity || 0) ||
undefined
)
}
},
{
name: 'taxRate',
label: 'Tax Rate',
type: 'object',
objectType: 'taxRate',
value: (objectData) => {
if (objectData?.item) {
console.log(objectData?.item)
return objectData?.item?.costTaxRate || undefined
} else {
return undefined
}
}
},
{
name: 'taxRate._id',
label: 'Tax Rate ID',
type: 'id',
showHyperlink: true,
objectType: 'taxRate',
value: (objectData) => {
return objectData?.taxRate?._id || undefined
}
},
{
name: 'totalCostWithTax',
label: 'Total Cost With Tax',
type: 'number',
required: true,
readOnly: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 175,
value: (objectData) => {
if (objectData?.taxRate?.rateType == 'percentage') {
return (
(
(objectData?.totalCost || 0) *
(1 + objectData?.taxRate?.rate / 100)
).toFixed(2) || undefined
)
} else if (objectData?.taxRate?.rateType == 'amount') {
return (
(
(objectData?.totalCost || 0) + objectData?.taxRate?.rate
).toFixed(2) || undefined
)
} else {
return objectData?.totalCost || undefined
}
}
}
],
rollups: [
{
name: 'totalQuantity',
label: 'Total',
type: 'number',
property: 'quantity',
value: (objectData) => {
return objectData?.items?.reduce(
(acc, item) => acc + item.quantity,
0
)
}
},
{
name: 'totalCost',
label: 'Total',
type: 'number',
prefix: '£',
property: 'totalCost',
value: (objectData) => {
return objectData?.items
?.reduce((acc, item) => acc + (item.totalCost || 0), 0)
.toFixed(2)
}
},
{
name: 'totalCostWithTax',
label: 'Total',
type: 'number',
prefix: '£',
property: 'totalCostWithTax',
value: (objectData) => {
return objectData?.items
?.reduce((acc, item) => acc + (item.totalCostWithTax || 0), 0)
.toFixed(2)
}
}
]
objectType: 'vendor',
showHyperlink: true
},
{
name: 'cost',

View File

@ -0,0 +1,280 @@
import ShipmentIcon from '../../components/Icons/ShipmentIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
export const Shipment = {
name: 'shipment',
label: 'Shipment',
prefix: 'SHM',
icon: ShipmentIcon,
actions: [
{
name: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon,
url: (_id) => `/dashboard/inventory/shipments/info?shipmentId=${_id}`
}
],
group: ['vendor', 'purchaseOrder'],
filters: ['vendor', 'purchaseOrder', 'state', 'courierService'],
sorters: [
'createdAt',
'state',
'updatedAt',
'shippedDate',
'expectedDeliveryDate'
],
columns: [
'_id',
'createdAt',
'state',
'updatedAt',
'vendor',
'purchaseOrder',
'trackingNumber'
],
properties: [
{
name: '_id',
label: 'ID',
type: 'id',
columnFixed: 'left',
objectType: 'shipment',
columnWidth: 140,
showCopy: true
},
{
name: 'createdAt',
label: 'Created At',
type: 'dateTime',
readOnly: true
},
{ name: 'state', label: 'State', type: 'state', readOnly: true },
{
name: 'updatedAt',
label: 'Updated At',
type: 'dateTime',
readOnly: true
},
{
name: 'purchaseOrder',
label: 'Purchase Order',
required: true,
type: 'object',
objectType: 'purchaseOrder',
showHyperlink: true
},
{
name: 'vendor',
label: 'Vendor',
required: true,
type: 'object',
objectType: 'vendor',
showHyperlink: true
},
{
name: 'courierService',
label: 'Courier Service',
required: false,
type: 'object',
objectType: 'courierService'
},
{
name: 'trackingNumber',
label: 'Tracking Number',
type: 'string',
required: false
},
{
name: 'items',
label: 'Shipment Items',
type: 'objectChildren',
required: true,
properties: [
{
name: 'itemType',
label: 'Item Type',
type: 'objectType',
masterFilter: ['part', 'packaging'],
required: true
},
{
name: 'item',
label: 'Item',
type: 'object',
objectType: (objectData) => {
return objectData?.itemType
},
required: true,
showHyperlink: true
},
{
name: 'itemCost',
label: 'Item Cost',
type: 'number',
required: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 150,
value: (objectData) => {
if (objectData?.item) {
return objectData?.item?.cost || undefined
} else {
return undefined
}
}
},
{
name: 'quantity',
label: 'Quantity',
type: 'number',
required: true,
columnWidth: 150
},
{
name: 'totalCost',
label: 'Total Cost',
type: 'number',
required: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 150,
value: (objectData) => {
return (
(objectData?.itemCost || 0) * (objectData?.quantity || 0) ||
undefined
)
}
},
{
name: 'taxRate',
label: 'Tax Rate',
type: 'object',
objectType: 'taxRate',
showHyperlink: true,
value: (objectData) => {
if (objectData?.item) {
return objectData?.item?.costTaxRate || undefined
} else {
return undefined
}
}
},
{
name: 'totalCostWithTax',
label: 'Total Cost w/ Tax',
type: 'number',
required: true,
readOnly: true,
prefix: '£',
min: 0,
step: 0.01,
columnWidth: 175,
value: (objectData) => {
if (objectData?.taxRate?.rateType == 'percentage') {
return (
(
(objectData?.totalCost || 0) *
(1 + objectData?.taxRate?.rate / 100)
).toFixed(2) || undefined
)
} else if (objectData?.taxRate?.rateType == 'amount') {
return (
(
(objectData?.totalCost || 0) + objectData?.taxRate?.rate
).toFixed(2) || undefined
)
} else {
return objectData?.totalCost || undefined
}
}
}
],
rollups: [
{
name: 'totalQuantity',
label: 'Total',
type: 'number',
property: 'quantity',
value: (objectData) => {
return objectData?.items?.reduce(
(acc, item) => acc + item.quantity,
0
)
}
},
{
name: 'totalCost',
label: 'Total',
type: 'number',
prefix: '£',
property: 'totalCost',
value: (objectData) => {
return objectData?.items
?.reduce((acc, item) => acc + (item.totalCost || 0), 0)
.toFixed(2)
}
},
{
name: 'totalCostWithTax',
label: 'Total',
type: 'number',
prefix: '£',
property: 'totalCostWithTax',
value: (objectData) => {
return objectData?.items
?.reduce((acc, item) => acc + (item.totalCostWithTax || 0), 0)
.toFixed(2)
}
}
]
},
{
name: 'cost',
label: 'Cost',
type: 'netGross',
required: true,
prefix: '£',
min: 0,
step: 0.01,
value: (objectData) => {
const net = objectData?.items?.reduce(
(acc, item) => acc + (item.totalCost || 0),
0
)
const gross = objectData?.items?.reduce(
(acc, item) => acc + (item.totalCostWithTax || 0),
0
)
return { net: net, gross: gross }
}
},
{
name: 'shippedDate',
label: 'Shipped Date',
type: 'dateTime',
required: false
},
{
name: 'expectedDeliveryDate',
label: 'Expected Delivery Date',
type: 'dateTime',
required: false
},
{
name: 'actualDeliveryDate',
label: 'Actual Delivery Date',
type: 'dateTime',
required: false
},
{
name: 'notes',
label: 'Notes',
type: 'textarea',
required: false
}
]
}

View File

@ -6,8 +6,8 @@ export const StockEvent = {
prefix: 'SEV',
icon: StockEventIcon,
actions: [],
columns: ['_id', 'owner', 'owner._id', 'parent._id', 'value', 'createdAt'],
filters: ['_id', 'owner._id', 'parent._id'],
columns: ['_id', 'owner', 'parent', 'value', 'createdAt'],
filters: ['_id', 'owner', 'parent'],
sorters: ['createdAt'],
properties: [
{
@ -42,18 +42,8 @@ export const StockEvent = {
},
columnFixed: 'left',
value: null,
showCopy: true
},
{
name: 'owner._id',
label: 'Owner ID',
type: 'id',
objectType: (objectData) => {
return objectData.ownerType
},
columnFixed: 'left',
showHyperlink: true,
showCopy: true
showCopy: true,
showHyperlink: true
},
{
name: 'parent',
@ -63,17 +53,8 @@ export const StockEvent = {
return objectData?.parentType
},
value: null,
showCopy: true
},
{
name: 'parent._id',
label: 'Parent ID',
type: 'id',
objectType: (objectData) => {
return objectData.parentType
},
showHyperlink: true,
showCopy: true
showCopy: true,
showHyperlink: true
},
{
name: 'value',

View File

@ -28,8 +28,8 @@ export const SubJob = {
}
}
],
columns: ['_id', 'printer', 'printer._id', 'job._id', 'state', 'createdAt'],
filters: ['state', '_id', 'job._id', 'printer._id'],
columns: ['_id', 'printer', 'job', 'state', 'createdAt'],
filters: ['state', '_id', 'job', 'printer'],
sorters: ['createdAt', 'state'],
group: ['job'],
properties: [
@ -102,15 +102,8 @@ export const SubJob = {
name: 'job',
label: 'Job',
type: 'object',
objectType: 'job'
},
{
name: 'job._id',
label: 'Job ID',
type: 'id',
columnWidth: 140,
showHyperlink: true,
objectType: 'job'
objectType: 'job',
showHyperlink: true
},
{
@ -118,16 +111,8 @@ export const SubJob = {
label: 'Printer',
type: 'object',
columnFixed: 'left',
objectType: 'printer'
},
{
name: 'printer._id',
label: 'Printer ID',
type: 'id',
columnWidth: 140,
columnFixed: 'left',
showHyperlink: true,
objectType: 'printer'
objectType: 'printer',
showHyperlink: true
}
]
}

View File

@ -101,15 +101,8 @@ export const TaxRecord = {
label: 'Tax Rate',
required: true,
type: 'object',
objectType: 'taxRate'
},
{
name: 'taxRate._id',
label: 'Tax Rate ID',
readOnly: true,
type: 'id',
showHyperlink: true,
objectType: 'taxRate'
objectType: 'taxRate',
showHyperlink: true
},
{
name: 'transactionType',
@ -129,17 +122,8 @@ export const TaxRecord = {
type: 'object',
objectType: (objectData) => {
return objectData?.transactionType || 'purchaseOrder'
}
},
{
name: 'transaction._id',
label: 'Transaction ID',
readOnly: true,
type: 'id',
showHyperlink: true,
objectType: (objectData) => {
return objectData?.transactionType || 'purchaseOrder'
}
showHyperlink: true
},
{
name: 'amount',