From 4501f9936f28b16601dec7289cf9ae482d8aee83 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 21 Jun 2026 21:19:49 +0100 Subject: [PATCH] Refactor ProductSku and PartSku models to enforce required fields for overrideCost, overridePrice, and related properties. Update visibility logic for cost and price fields based on overrides, ensuring consistent data handling across components. Adjust NewProductSku and ProductInfo components to utilize updated default values and improve user experience. --- .../Management/ProductSkus/NewProductSku.jsx | 52 ++----- .../Management/Products/ProductInfo.jsx | 2 +- src/database/models/PartSku.js | 140 ++++++++++++------ src/database/models/ProductSku.js | 131 +++++++++++----- 4 files changed, 201 insertions(+), 124 deletions(-) diff --git a/src/components/Dashboard/Management/ProductSkus/NewProductSku.jsx b/src/components/Dashboard/Management/ProductSkus/NewProductSku.jsx index 50fc676..7cb4187 100644 --- a/src/components/Dashboard/Management/ProductSkus/NewProductSku.jsx +++ b/src/components/Dashboard/Management/ProductSkus/NewProductSku.jsx @@ -8,7 +8,11 @@ const NewProductSku = ({ onOk, reset, defaultValues }) => { {({ handleSubmit, submitLoading, objectData, formValid }) => { const steps = [ @@ -50,51 +54,18 @@ const NewProductSku = ({ onOk, reset, defaultValues }) => { - ) - }, - { - title: 'Parts', - key: 'parts', - content: ( - { createdAt: false, updatedAt: false, _id: false, - _reference: false + _reference: false, + parts: false }} - labelWidth={100} + labelWidth={120} bordered={false} isEditing={false} objectData={objectData} diff --git a/src/components/Dashboard/Management/Products/ProductInfo.jsx b/src/components/Dashboard/Management/Products/ProductInfo.jsx index cf4e92d..29bfdd3 100644 --- a/src/components/Dashboard/Management/Products/ProductInfo.jsx +++ b/src/components/Dashboard/Management/Products/ProductInfo.jsx @@ -197,7 +197,7 @@ const ProductInfo = () => { }} reset={newProductSkuOpen} defaultValues={{ - product: productId ? { _id: productId } : undefined + product: objectFormState?.objectData || undefined }} /> diff --git a/src/database/models/PartSku.js b/src/database/models/PartSku.js index 4685601..56d5794 100644 --- a/src/database/models/PartSku.js +++ b/src/database/models/PartSku.js @@ -75,7 +75,17 @@ export const PartSku = { 'createdAt', 'updatedAt' ], - filters: ['_id', 'barcode', 'part', 'part._id', 'name', 'cost', 'costWithTax', 'price', 'priceWithTax'], + filters: [ + '_id', + 'barcode', + 'part', + 'part._id', + 'name', + 'cost', + 'costWithTax', + 'price', + 'priceWithTax' + ], sorters: [ 'barcode', 'part', @@ -152,54 +162,44 @@ export const PartSku = { type: 'text', columnWidth: 200 }, - { - name: 'priceMode', - label: 'Price Mode', - required: false, - type: 'priceMode', - columnWidth: 150 - }, { name: 'overrideCost', label: 'Override Cost', - required: false, + required: true, type: 'bool', - value: (objectData) => objectData?.overrideCost ?? false, - columnWidth: 150 - }, - { - name: 'overridePrice', - label: 'Override Price', - required: false, - type: 'bool', - value: (objectData) => objectData?.overridePrice ?? false, columnWidth: 150 }, + { name: 'cost', label: 'Cost', - required: false, + required: true, type: 'number', prefix: '£', min: 0, step: 0.01, - disabled: (objectData) => !objectData?.overrideCost, + visible: (objectData) => { + return objectData?.overrideCost + }, value: (objectData) => - objectData?.overrideCost ? objectData?.cost : undefined, + objectData?.overrideCost ? objectData?.cost : objectData?.part?.cost, columnWidth: 100 }, { name: 'costWithTax', label: 'Cost w/ Tax', - required: false, + required: true, readOnly: true, type: 'number', prefix: '£', min: 0, step: 0.01, - disabled: (objectData) => !objectData?.overrideCost, + visible: (objectData) => { + return objectData?.overrideCost + }, value: (objectData) => { - if (!objectData?.overrideCost) return undefined + if (!objectData?.overrideCost) + return objectData?.part?.costWithTax || undefined const cost = objectData?.cost const taxRate = objectData?.costTaxRate if (!cost) return 0 @@ -215,28 +215,58 @@ export const PartSku = { { name: 'costTaxRate', label: 'Cost Tax Rate', - required: false, + required: true, type: 'object', objectType: 'taxRate', showHyperlink: true, - disabled: (objectData) => !objectData?.overrideCost, + visible: (objectData) => { + return objectData?.overrideCost + }, value: (objectData) => - objectData?.overrideCost ? objectData?.costTaxRate : undefined, + objectData?.overrideCost + ? objectData?.costTaxRate + : objectData?.part?.costTaxRate, + columnWidth: 150 + }, + { + name: 'overridePrice', + label: 'Override Price', + required: true, + type: 'bool', + columnWidth: 150 + }, + { + name: 'priceMode', + label: 'Price Mode', + required: true, + visible: (objectData) => { + return objectData?.overridePrice + }, + value: (objectData) => { + return objectData?.overridePrice + ? objectData?.priceMode + : objectData?.part?.priceMode + }, + type: 'priceMode', columnWidth: 150 }, { name: 'price', label: 'Price', - required: false, + required: true, type: 'number', prefix: '£', min: 0, step: 0.1, - disabled: (objectData) => !objectData?.overridePrice, + fixedNumber: 2, + visible: (objectData) => { + return objectData?.overridePrice + }, readOnly: (objectData) => objectData?.overridePrice && objectData?.priceMode == 'margin', value: (objectData) => { - if (!objectData?.overridePrice) return undefined + if (!objectData?.overridePrice) + return objectData?.part?.price || undefined const priceMode = objectData?.priceMode ?? objectData?.part?.priceMode const cost = objectData?.overrideCost ? objectData?.cost @@ -248,7 +278,7 @@ export const PartSku = { margin !== null && cost != null ) { - return (cost * (1 + margin / 100)).toFixed(2) || undefined + return cost * (1 + margin / 100) || undefined } return objectData?.price }, @@ -257,15 +287,18 @@ export const PartSku = { { name: 'priceWithTax', label: 'Price w/ Tax', - required: false, + required: true, readOnly: true, type: 'number', prefix: '£', min: 0, step: 0.01, - disabled: (objectData) => !objectData?.overridePrice, + visible: (objectData) => { + return objectData?.overridePrice + }, value: (objectData) => { - if (!objectData?.overridePrice) return undefined + if (!objectData?.overridePrice) + return objectData.part?.priceWithTax || undefined let price const priceMode = objectData?.priceMode ?? objectData?.part?.priceMode const cost = objectData?.overrideCost @@ -292,28 +325,51 @@ export const PartSku = { { name: 'margin', label: 'Margin', - required: false, + required: true, type: 'number', - disabled: (objectData) => - !objectData?.overridePrice || objectData?.priceMode == 'amount', + visible: (objectData) => { + return objectData?.overridePrice + }, + readOnly: (objectData) => { + const priceMode = objectData?.priceMode ?? objectData?.part?.priceMode + return priceMode == 'amount' + }, suffix: '%', min: 0, max: 100, step: 0.01, - value: (objectData) => - objectData?.overridePrice ? objectData?.margin : undefined, + value: (objectData) => { + if (!objectData?.overridePrice) + return objectData?.part?.margin || undefined + const priceMode = objectData?.priceMode ?? objectData?.part?.priceMode + const cost = objectData?.overrideCost + ? objectData?.cost + : objectData?.part?.cost + if (priceMode == 'amount') { + const price = objectData?.price + if (price != null && cost != null) { + return Number(((price / cost - 1) * 100).toFixed(2)) || undefined + } + return undefined + } + return objectData?.margin ?? objectData?.part?.margin + }, columnWidth: 85 }, { name: 'priceTaxRate', label: 'Price Tax Rate', - required: false, + required: true, type: 'object', objectType: 'taxRate', showHyperlink: true, - disabled: (objectData) => !objectData?.overridePrice, + visible: (objectData) => { + return objectData?.overridePrice + }, value: (objectData) => - objectData?.overridePrice ? objectData?.priceTaxRate : undefined, + objectData?.overridePrice + ? objectData?.priceTaxRate + : objectData?.part?.priceTaxRate, columnWidth: 150 } ] diff --git a/src/database/models/ProductSku.js b/src/database/models/ProductSku.js index c5136b3..ad3bac4 100644 --- a/src/database/models/ProductSku.js +++ b/src/database/models/ProductSku.js @@ -163,54 +163,45 @@ export const ProductSku = { type: 'text', columnWidth: 200 }, - { - name: 'priceMode', - label: 'Price Mode', - required: false, - type: 'priceMode', - columnWidth: 150 - }, { name: 'overrideCost', label: 'Override Cost', - required: false, + required: true, type: 'bool', - value: (objectData) => objectData?.overrideCost ?? false, - columnWidth: 150 - }, - { - name: 'overridePrice', - label: 'Override Price', - required: false, - type: 'bool', - value: (objectData) => objectData?.overridePrice ?? false, columnWidth: 150 }, { name: 'cost', label: 'Cost', - required: false, + required: true, type: 'number', prefix: '£', min: 0, step: 0.01, - disabled: (objectData) => !objectData?.overrideCost, + visible: (objectData) => { + return objectData?.overrideCost + }, value: (objectData) => - objectData?.overrideCost ? objectData?.cost : undefined, + objectData?.overrideCost + ? objectData?.cost + : objectData?.product?.cost, columnWidth: 100 }, { name: 'costWithTax', label: 'Cost w/ Tax', - required: false, + required: true, readOnly: true, type: 'number', prefix: '£', min: 0, step: 0.01, - disabled: (objectData) => !objectData?.overrideCost, + visible: (objectData) => { + return objectData?.overrideCost + }, value: (objectData) => { - if (!objectData?.overrideCost) return undefined + if (!objectData?.overrideCost) + return objectData?.product?.costWithTax || undefined const cost = objectData?.cost const taxRate = objectData?.costTaxRate if (!cost) return 0 @@ -226,28 +217,58 @@ export const ProductSku = { { name: 'costTaxRate', label: 'Cost Tax Rate', - required: false, + required: true, type: 'object', objectType: 'taxRate', showHyperlink: true, - disabled: (objectData) => !objectData?.overrideCost, + visible: (objectData) => { + return objectData?.overrideCost + }, value: (objectData) => - objectData?.overrideCost ? objectData?.costTaxRate : undefined, + objectData?.overrideCost + ? objectData?.costTaxRate + : objectData?.product?.costTaxRate, + columnWidth: 150 + }, + { + name: 'overridePrice', + label: 'Override Price', + required: true, + type: 'bool', + columnWidth: 150 + }, + { + name: 'priceMode', + label: 'Price Mode', + required: true, + visible: (objectData) => { + return objectData?.overridePrice + }, + value: (objectData) => { + return objectData?.overridePrice + ? objectData?.priceMode + : objectData?.product?.priceMode + }, + type: 'priceMode', columnWidth: 150 }, { name: 'price', label: 'Price', - required: false, + required: true, type: 'number', prefix: '£', min: 0, step: 0.1, - disabled: (objectData) => !objectData?.overridePrice, + fixedNumber: 2, + visible: (objectData) => { + return objectData?.overridePrice + }, readOnly: (objectData) => objectData?.overridePrice && objectData?.priceMode == 'margin', value: (objectData) => { - if (!objectData?.overridePrice) return undefined + if (!objectData?.overridePrice) + return objectData?.product?.price || undefined const priceMode = objectData?.priceMode ?? objectData?.product?.priceMode const cost = objectData?.overrideCost @@ -260,7 +281,7 @@ export const ProductSku = { margin !== null && cost != null ) { - return (cost * (1 + margin / 100)).toFixed(2) || undefined + return cost * (1 + margin / 100) || undefined } return objectData?.price }, @@ -269,15 +290,18 @@ export const ProductSku = { { name: 'priceWithTax', label: 'Price w/ Tax', - required: false, + required: true, readOnly: true, type: 'number', prefix: '£', min: 0, step: 0.01, - disabled: (objectData) => !objectData?.overridePrice, + visible: (objectData) => { + return objectData?.overridePrice + }, value: (objectData) => { - if (!objectData?.overridePrice) return undefined + if (!objectData?.overridePrice) + return objectData.product?.priceWithTax || undefined let price const priceMode = objectData?.priceMode ?? objectData?.product?.priceMode @@ -305,28 +329,53 @@ export const ProductSku = { { name: 'margin', label: 'Margin', - required: false, + required: true, type: 'number', - disabled: (objectData) => - !objectData?.overridePrice || objectData?.priceMode == 'amount', + visible: (objectData) => { + return objectData?.overridePrice + }, + readOnly: (objectData) => { + const priceMode = + objectData?.priceMode ?? objectData?.product?.priceMode + return priceMode == 'amount' + }, suffix: '%', min: 0, max: 100, step: 0.01, - value: (objectData) => - objectData?.overridePrice ? objectData?.margin : undefined, + value: (objectData) => { + if (!objectData?.overridePrice) + return objectData?.product?.margin || undefined + const priceMode = + objectData?.priceMode ?? objectData?.product?.priceMode + const cost = objectData?.overrideCost + ? objectData?.cost + : objectData?.product?.cost + if (priceMode == 'amount') { + const price = objectData?.price + if (price != null && cost != null) { + return Number(((price / cost - 1) * 100).toFixed(2)) || undefined + } + return undefined + } + return objectData?.margin ?? objectData?.product?.margin + }, columnWidth: 85 }, { name: 'priceTaxRate', label: 'Price Tax Rate', - required: false, + required: true, type: 'object', objectType: 'taxRate', showHyperlink: true, - disabled: (objectData) => !objectData?.overridePrice, + visible: (objectData) => { + return objectData?.overridePrice + }, value: (objectData) => - objectData?.overridePrice ? objectData?.priceTaxRate : undefined, + objectData?.overridePrice + ? objectData?.priceTaxRate + : objectData?.product?.priceTaxRate, columnWidth: 150 }, {