From f24bc27e2c870e625cb940af4587b988bc72f470 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 7 Dec 2025 02:41:17 +0000 Subject: [PATCH] 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. --- src/database/ObjectModels.js | 6 + src/database/models/AuditLog.js | 32 +-- src/database/models/CourierService.js | 12 +- src/database/models/DocumentJob.js | 28 +-- src/database/models/DocumentPrinter.js | 27 +-- src/database/models/DocumentTemplate.js | 19 -- src/database/models/Filament.js | 10 +- src/database/models/FilamentStock.js | 12 +- src/database/models/GCodeFile.js | 32 +-- src/database/models/Job.js | 11 +- src/database/models/Note.js | 45 ++-- src/database/models/OrderItem.js | 214 ++++++++++++++++++ src/database/models/Part.js | 55 +---- src/database/models/PartStock.js | 37 +--- src/database/models/Printer.js | 66 +----- src/database/models/Product.js | 27 +-- src/database/models/PurchaseOrder.js | 192 ++-------------- src/database/models/Shipment.js | 280 ++++++++++++++++++++++++ src/database/models/StockEvent.js | 31 +-- src/database/models/SubJob.js | 27 +-- src/database/models/TaxRecord.js | 24 +- 21 files changed, 605 insertions(+), 582 deletions(-) create mode 100644 src/database/models/OrderItem.js create mode 100644 src/database/models/Shipment.js diff --git a/src/database/ObjectModels.js b/src/database/ObjectModels.js index 6e90e32..64162cf 100644 --- a/src/database/ObjectModels.js +++ b/src/database/ObjectModels.js @@ -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, diff --git a/src/database/models/AuditLog.js b/src/database/models/AuditLog.js index ab0c466..ed71114 100644 --- a/src/database/models/AuditLog.js +++ b/src/database/models/AuditLog.js @@ -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', diff --git a/src/database/models/CourierService.js b/src/database/models/CourierService.js index 8869cf9..9411527 100644 --- a/src/database/models/CourierService.js +++ b/src/database/models/CourierService.js @@ -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', diff --git a/src/database/models/DocumentJob.js b/src/database/models/DocumentJob.js index 68d8732..27d1f6c 100644 --- a/src/database/models/DocumentJob.js +++ b/src/database/models/DocumentJob.js @@ -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' } ] } diff --git a/src/database/models/DocumentPrinter.js b/src/database/models/DocumentPrinter.js index eb723af..b08bcbc 100644 --- a/src/database/models/DocumentPrinter.js +++ b/src/database/models/DocumentPrinter.js @@ -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 }, { diff --git a/src/database/models/DocumentTemplate.js b/src/database/models/DocumentTemplate.js index 04decd8..9b4f133 100644 --- a/src/database/models/DocumentTemplate.js +++ b/src/database/models/DocumentTemplate.js @@ -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 } diff --git a/src/database/models/Filament.js b/src/database/models/Filament.js index 63003be..065e8a1 100644 --- a/src/database/models/Filament.js +++ b/src/database/models/Filament.js @@ -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 }, { diff --git a/src/database/models/FilamentStock.js b/src/database/models/FilamentStock.js index 0a8498e..ce22df8 100644 --- a/src/database/models/FilamentStock.js +++ b/src/database/models/FilamentStock.js @@ -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', diff --git a/src/database/models/GCodeFile.js b/src/database/models/GCodeFile.js index db83212..5f89654 100644 --- a/src/database/models/GCodeFile.js +++ b/src/database/models/GCodeFile.js @@ -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', diff --git a/src/database/models/Job.js b/src/database/models/Job.js index bb626ed..a80670a 100644 --- a/src/database/models/Job.js +++ b/src/database/models/Job.js @@ -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 } ] diff --git a/src/database/models/Note.js b/src/database/models/Note.js index 8a8377b..5165a18 100644 --- a/src/database/models/Note.js +++ b/src/database/models/Note.js @@ -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 } ] } diff --git a/src/database/models/OrderItem.js b/src/database/models/OrderItem.js new file mode 100644 index 0000000..70f0123 --- /dev/null +++ b/src/database/models/OrderItem.js @@ -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 + } + } + } + ] +} diff --git a/src/database/models/Part.js b/src/database/models/Part.js index b9f30fb..a5a00ad 100644 --- a/src/database/models/Part.js +++ b/src/database/models/Part.js @@ -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 } ] diff --git a/src/database/models/PartStock.js b/src/database/models/PartStock.js index 0c1ea3a..2ce318c 100644 --- a/src/database/models/PartStock.js +++ b/src/database/models/PartStock.js @@ -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 } ] } diff --git a/src/database/models/Printer.js b/src/database/models/Printer.js index 094c4d9..30fc7a5 100644 --- a/src/database/models/Printer.js +++ b/src/database/models/Printer.js @@ -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', diff --git a/src/database/models/Product.js b/src/database/models/Product.js index 2aad532..13e8651 100644 --- a/src/database/models/Product.js +++ b/src/database/models/Product.js @@ -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', diff --git a/src/database/models/PurchaseOrder.js b/src/database/models/PurchaseOrder.js index 1294577..8d366d7 100644 --- a/src/database/models/PurchaseOrder.js +++ b/src/database/models/PurchaseOrder.js @@ -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', diff --git a/src/database/models/Shipment.js b/src/database/models/Shipment.js new file mode 100644 index 0000000..e5d22ed --- /dev/null +++ b/src/database/models/Shipment.js @@ -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 + } + ] +} diff --git a/src/database/models/StockEvent.js b/src/database/models/StockEvent.js index 2ef3f2b..115fb48 100644 --- a/src/database/models/StockEvent.js +++ b/src/database/models/StockEvent.js @@ -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', diff --git a/src/database/models/SubJob.js b/src/database/models/SubJob.js index 277d67a..9eec9fc 100644 --- a/src/database/models/SubJob.js +++ b/src/database/models/SubJob.js @@ -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 } ] } diff --git a/src/database/models/TaxRecord.js b/src/database/models/TaxRecord.js index 07f163d..852cd8a 100644 --- a/src/database/models/TaxRecord.js +++ b/src/database/models/TaxRecord.js @@ -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',