Add Stock Audit Level Management Features and Enhance Stock Audit Components
- Introduced Stock Audit Level management components, including StockAuditLevels, NewStockAuditLevel, and StockAuditLevelInfo, to facilitate the creation and management of stock audit levels. - Enhanced existing StockAudit components by adding a PostStockAudit feature for posting stock audits and updating the NewStockAudit form to handle draft states. - Updated StockAuditInfo to include new properties and improved visibility settings for audit lines, enhancing user experience and data representation. - Refactored ObjectModels and sidebar configurations to integrate Stock Audit Levels into the management dashboard, improving navigation and accessibility. - Added new utility functions and improved data handling across components to ensure seamless integration and performance.
This commit is contained in:
parent
a5b888333d
commit
972fdb62ad
@ -1,17 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
<g transform="matrix(1.0066,0,0,1.0066,5.43531,-1.54828)">
|
<path d="M32.468,59.712C32.725,59.914 32.837,60.249 32.754,60.565C32.671,60.881 32.408,61.117 32.085,61.166C31.147,61.264 30.216,61.073 29.3,60.555L8.262,48.803C5.729,47.378 4.441,45.879 4.441,42.127L4.441,20.65C4.441,17.814 5.489,16.02 7.877,14.692L26.541,4.215C29.828,2.367 33.176,2.367 36.463,4.215L55.149,14.692C57.515,16.02 58.563,17.814 58.563,20.65C58.563,21.207 58.294,21.73 57.84,22.053C57.386,22.376 56.804,22.46 56.278,22.277C53.589,21.35 50.911,20.452 49.823,20.095C49.813,20.092 49.803,20.089 49.793,20.086C49.564,20.017 49.398,19.817 49.372,19.579C49.346,19.341 49.464,19.11 49.673,18.993C49.673,18.992 49.674,18.992 49.674,18.992C49.978,18.821 50.166,18.499 50.166,18.15C50.167,17.801 49.979,17.479 49.674,17.307C45.559,14.986 34.365,8.675 34.365,8.675C32.407,7.556 30.587,7.587 28.656,8.675L24.257,11.165C24.257,11.165 34.347,16.813 39.002,19.419C39.405,19.645 39.637,20.087 39.595,20.547C39.553,21.007 39.244,21.399 38.807,21.548C37.999,21.826 37.152,22.12 36.313,22.416C35.556,22.682 34.72,22.61 34.021,22.217C30.425,20.197 19.274,13.934 19.274,13.934L11.856,18.15C11.856,18.15 22.923,24.355 26.284,26.24C26.797,26.528 27.006,27.16 26.765,27.696C26.444,28.447 26.307,29.369 26.307,30.532C26.307,30.829 26.149,31.104 25.892,31.254C25.635,31.404 25.318,31.406 25.06,31.26C21.115,29.032 9.169,22.284 9.169,22.284L9.169,41.664C9.169,43.059 9.681,43.919 11.137,44.722C11.137,44.722 22.059,50.89 26.083,53.162C27.034,53.7 27.832,54.471 28.402,55.402C29.329,56.93 30.681,58.316 32.468,59.712Z" style="fill-rule:nonzero;"/>
|
||||||
<path d="M26.391,65.119C26.941,65.119 27.788,64.903 28.58,64.471C46.553,54.66 52.781,50.171 52.781,38.771L52.781,15.146C52.781,11.443 51.347,10.136 48.246,8.814C44.773,7.367 33.063,3.249 29.657,2.086C28.622,1.754 27.44,1.538 26.391,1.538C25.341,1.538 24.159,1.811 23.15,2.086C19.744,3.058 8.009,7.393 4.535,8.814C1.46,10.11 0,11.443 0,15.146L0,38.771C0,50.171 6.254,54.634 24.201,64.471C25.019,64.903 25.84,65.119 26.391,65.119ZM26.391,58.557C25.941,58.557 25.498,58.392 24.588,57.841C10.303,49.13 5.869,46.787 5.869,37.603L5.869,16.142C5.869,15.041 6.079,14.601 6.965,14.251C11.591,12.416 20.574,9.417 24.758,7.773C25.461,7.509 25.946,7.419 26.391,7.419C26.836,7.419 27.315,7.535 28.023,7.773C32.208,9.417 41.139,12.595 45.842,14.251C46.697,14.575 46.913,15.041 46.913,16.142L46.913,37.603C46.913,46.838 42.321,49.318 28.193,57.841C27.309,58.386 26.84,58.557 26.391,58.557Z" style="fill-rule:nonzero;"/>
|
<g transform="matrix(0.652268,0,0,0.652268,28.5941,21.1337)">
|
||||||
</g>
|
<path d="M27.141,65.719C27.781,65.719 28.688,65.453 29.5,65.031C47.813,55.5 54.281,50.531 54.281,39.141L54.281,16.016C54.281,11.563 52.797,9.766 48.906,8.094C45.813,6.797 34.453,2.969 31.547,2.016C30.172,1.594 28.5,1.328 27.141,1.328C25.781,1.328 24.109,1.641 22.75,2.016C19.844,2.828 8.469,6.813 5.375,8.094C1.5,9.75 0,11.563 0,16.016L0,39.141C0,50.531 6.484,55.484 24.781,65.031C25.609,65.453 26.5,65.719 27.141,65.719ZM27.141,57.547C26.781,57.547 26.438,57.422 25.578,56.891C11.563,48.25 7.469,46.297 7.469,37.953L7.469,17.063C7.469,15.891 7.719,15.391 8.625,15.031C13.031,13.266 21.594,10.438 24.828,9.203C25.891,8.859 26.516,8.719 27.141,8.719C27.766,8.719 28.375,8.875 29.453,9.203C32.688,10.438 41.219,13.375 45.672,15.031C46.547,15.375 46.813,15.891 46.813,17.063L46.813,37.953C46.813,46.438 42.281,48.828 28.703,56.891C27.859,57.406 27.5,57.547 27.141,57.547Z" style="fill-rule:nonzero;"/>
|
||||||
<g transform="matrix(1,0,0,1,0,3.06619)">
|
<g transform="matrix(0,-1.228947,0.741699,0,5.037355,87.672304)">
|
||||||
<g transform="matrix(6.59906e-17,-1.07771,0.650424,3.9827e-17,12.7469,98.4759)">
|
|
||||||
<path d="M58.139,21.607C58.139,19.1 56.911,17.066 55.398,17.066C53.885,17.066 52.657,19.1 52.657,21.607L52.657,37.595C52.657,40.101 53.885,42.136 55.398,42.136C56.911,42.136 58.139,40.101 58.139,37.595L58.139,21.607Z"/>
|
<path d="M58.139,21.607C58.139,19.1 56.911,17.066 55.398,17.066C53.885,17.066 52.657,19.1 52.657,21.607L52.657,37.595C52.657,40.101 53.885,42.136 55.398,42.136C56.911,42.136 58.139,40.101 58.139,37.595L58.139,21.607Z"/>
|
||||||
</g>
|
</g>
|
||||||
<g transform="matrix(6.59906e-17,-1.07771,0.650424,3.9827e-17,12.7469,76.7291)">
|
<g transform="matrix(0,-1.228947,0.741699,0,5.037355,112.47087)">
|
||||||
<path d="M58.139,21.607C58.139,19.1 56.911,17.066 55.398,17.066C53.885,17.066 52.657,19.1 52.657,21.607L52.657,37.595C52.657,40.101 53.885,42.136 55.398,42.136C56.911,42.136 58.139,40.101 58.139,37.595L58.139,21.607Z"/>
|
<path d="M58.139,21.607C58.139,19.1 56.911,17.066 55.398,17.066C53.885,17.066 52.657,19.1 52.657,21.607L52.657,37.595C52.657,40.101 53.885,42.136 55.398,42.136C56.911,42.136 58.139,40.101 58.139,37.595L58.139,21.607Z"/>
|
||||||
</g>
|
</g>
|
||||||
<g transform="matrix(6.59906e-17,-1.07771,1.05902,6.48461e-17,0.652146,87.6054)">
|
<g transform="matrix(0,-1.228947,1.207634,0,-8.754676,100.074894)">
|
||||||
<path d="M58.139,19.855C58.139,18.315 56.911,17.066 55.398,17.066C53.885,17.066 52.657,18.315 52.657,19.855L52.657,39.347C52.657,40.886 53.885,42.136 55.398,42.136C56.911,42.136 58.139,40.886 58.139,39.347L58.139,19.855Z"/>
|
<path d="M58.139,19.855C58.139,18.315 56.911,17.066 55.398,17.066C53.885,17.066 52.657,18.315 52.657,19.855L52.657,39.347C52.657,40.886 53.885,42.136 55.398,42.136C56.911,42.136 58.139,40.886 58.139,39.347L58.139,19.855Z"/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 3.8 KiB |
@ -6,9 +6,9 @@ import WizardView from '../../common/WizardView'
|
|||||||
const NewStockAudit = ({ onOk, reset, defaultValues }) => {
|
const NewStockAudit = ({ onOk, reset, defaultValues }) => {
|
||||||
return (
|
return (
|
||||||
<NewObjectForm
|
<NewObjectForm
|
||||||
type={'stockAudit'}
|
type='stockAudit'
|
||||||
reset={reset}
|
reset={reset}
|
||||||
defaultValues={{ state: { type: 'new' }, ...defaultValues }}
|
defaultValues={{ state: { type: 'draft' }, auditLines: [], ...defaultValues }}
|
||||||
>
|
>
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
||||||
const steps = [
|
const steps = [
|
||||||
@ -23,6 +23,7 @@ const NewStockAudit = ({ onOk, reset, defaultValues }) => {
|
|||||||
isEditing={true}
|
isEditing={true}
|
||||||
required={true}
|
required={true}
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
|
visibleProperties={{ auditLines: false }}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -38,7 +39,8 @@ const NewStockAudit = ({ onOk, reset, defaultValues }) => {
|
|||||||
_id: false,
|
_id: false,
|
||||||
_reference: false,
|
_reference: false,
|
||||||
createdAt: false,
|
createdAt: false,
|
||||||
updatedAt: false
|
updatedAt: false,
|
||||||
|
auditLines: false
|
||||||
}}
|
}}
|
||||||
isEditing={false}
|
isEditing={false}
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
import { useState, useContext } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { ApiServerContext } from '../../context/ApiServerContext'
|
||||||
|
import { message } from 'antd'
|
||||||
|
import MessageDialogView from '../../common/MessageDialogView.jsx'
|
||||||
|
|
||||||
|
const PostStockAudit = ({ onOk, objectData }) => {
|
||||||
|
const [postLoading, setPostLoading] = useState(false)
|
||||||
|
const { sendObjectFunction } = useContext(ApiServerContext)
|
||||||
|
|
||||||
|
const handlePost = async () => {
|
||||||
|
setPostLoading(true)
|
||||||
|
try {
|
||||||
|
const result = await sendObjectFunction(
|
||||||
|
objectData._id,
|
||||||
|
'StockAudit',
|
||||||
|
'post'
|
||||||
|
)
|
||||||
|
if (result) {
|
||||||
|
message.success('Stock audit posted')
|
||||||
|
onOk(result)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error posting stock audit:', error)
|
||||||
|
} finally {
|
||||||
|
setPostLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MessageDialogView
|
||||||
|
title={'Post this stock audit?'}
|
||||||
|
description={`Posting will create stock events for audit lines with variance, adjust stock for each SKU at the selected location, and mark this audit as complete.`}
|
||||||
|
onOk={handlePost}
|
||||||
|
okText='Post'
|
||||||
|
okLoading={postLoading}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
PostStockAudit.propTypes = {
|
||||||
|
onOk: PropTypes.func.isRequired,
|
||||||
|
objectData: PropTypes.object
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PostStockAudit
|
||||||
@ -8,10 +8,12 @@ import useCollapseState from '../../hooks/useCollapseState.jsx'
|
|||||||
import NotesPanel from '../../common/NotesPanel.jsx'
|
import NotesPanel from '../../common/NotesPanel.jsx'
|
||||||
import InfoCollapse from '../../common/InfoCollapse.jsx'
|
import InfoCollapse from '../../common/InfoCollapse.jsx'
|
||||||
import ObjectInfo from '../../common/ObjectInfo.jsx'
|
import ObjectInfo from '../../common/ObjectInfo.jsx'
|
||||||
|
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
||||||
import ViewButton from '../../common/ViewButton.jsx'
|
import ViewButton from '../../common/ViewButton.jsx'
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
||||||
|
import StockAuditIcon from '../../../Icons/StockAuditIcon.jsx'
|
||||||
import ObjectForm from '../../common/ObjectForm.jsx'
|
import ObjectForm from '../../common/ObjectForm.jsx'
|
||||||
import EditButtons from '../../common/EditButtons.jsx'
|
import EditButtons from '../../common/EditButtons.jsx'
|
||||||
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
|
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
|
||||||
@ -23,7 +25,7 @@ import ObjectTable from '../../common/ObjectTable.jsx'
|
|||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
||||||
import { getModelByName } from '../../../../database/ObjectModels.js'
|
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
|
|
||||||
const log = loglevel.getLogger('StockAuditInfo')
|
const log = loglevel.getLogger('StockAuditInfo')
|
||||||
@ -38,7 +40,7 @@ const StockAuditInfo = () => {
|
|||||||
'StockAuditInfo',
|
'StockAuditInfo',
|
||||||
{
|
{
|
||||||
info: true,
|
info: true,
|
||||||
stocks: true,
|
auditLines: true,
|
||||||
notes: true,
|
notes: true,
|
||||||
auditLogs: false
|
auditLogs: false
|
||||||
}
|
}
|
||||||
@ -83,163 +85,177 @@ const StockAuditInfo = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Flex
|
||||||
<Flex
|
gap='large'
|
||||||
gap='large'
|
vertical='true'
|
||||||
vertical='true'
|
style={{
|
||||||
style={{
|
maxHeight: '100%',
|
||||||
maxHeight: '100%',
|
minHeight: 0
|
||||||
minHeight: 0
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<Flex justify={'space-between'}>
|
||||||
<Flex justify={'space-between'}>
|
<Space size='small'>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Space size='small'>
|
<ObjectActions
|
||||||
<ObjectActions
|
type='stockAudit'
|
||||||
type='stockAudit'
|
|
||||||
pageName='info'
|
pageName='info'
|
||||||
id={stockAuditId}
|
id={stockAuditId}
|
||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
objectData={objectFormState.objectData}
|
objectData={objectFormState.objectData}
|
||||||
/>
|
/>
|
||||||
<ViewButton
|
<ViewButton
|
||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
items={[
|
items={[
|
||||||
{ key: 'info', label: 'Stock Audit Information' },
|
{ key: 'info', label: 'Stock Audit Information' },
|
||||||
{ key: 'notes', label: 'Notes' },
|
{ key: 'auditLines', label: 'Audit Lines' },
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
{ key: 'notes', label: 'Notes' },
|
||||||
]}
|
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||||
visibleState={collapseState}
|
]}
|
||||||
updateVisibleState={updateCollapseState}
|
visibleState={collapseState}
|
||||||
/>
|
updateVisibleState={updateCollapseState}
|
||||||
<UserNotifierToggle
|
/>
|
||||||
type='stockAudit'
|
<UserNotifierToggle
|
||||||
objectData={objectFormState.objectData}
|
type='stockAudit'
|
||||||
disabled={objectFormState.loading}
|
objectData={objectFormState.objectData}
|
||||||
/>
|
disabled={objectFormState.loading}
|
||||||
<DocumentPrintButton
|
/>
|
||||||
type='stockAudit'
|
<DocumentPrintButton
|
||||||
objectData={objectFormState.objectData}
|
type='stockAudit'
|
||||||
disabled={objectFormState.loading}
|
objectData={objectFormState.objectData}
|
||||||
/>
|
disabled={objectFormState.loading}
|
||||||
</Space>
|
|
||||||
<ActivityIndicator
|
|
||||||
activities={objectFormState.activities}
|
|
||||||
showStartingDivider={true}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<ActivityIndicator
|
||||||
<EditButtons
|
activities={objectFormState.activities}
|
||||||
isEditing={objectFormState.isEditing}
|
showStartingDivider={true}
|
||||||
handleUpdate={() => {
|
/>
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
</Space>
|
||||||
}}
|
<Space>
|
||||||
cancelEditing={() => {
|
<EditButtons
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
isEditing={objectFormState.isEditing}
|
||||||
}}
|
handleUpdate={() => {
|
||||||
startEditing={() => {
|
actionHandlerRef.current.callAction('finishEdit')
|
||||||
actionHandlerRef.current.callAction('edit')
|
}}
|
||||||
}}
|
cancelEditing={() => {
|
||||||
editLoading={objectFormState.editLoading}
|
actionHandlerRef.current.callAction('cancelEdit')
|
||||||
formValid={objectFormState.formValid}
|
}}
|
||||||
disabled={
|
startEditing={() => {
|
||||||
objectFormState.beingEditedByOther ||
|
actionHandlerRef.current.callAction('edit')
|
||||||
objectFormState.loading ||
|
}}
|
||||||
objectFormState.editDisabled
|
editLoading={objectFormState.editLoading}
|
||||||
}
|
formValid={objectFormState.formValid}
|
||||||
loading={objectFormState.editLoading}
|
disabled={
|
||||||
/>
|
objectFormState.beingEditedByOther ||
|
||||||
</Space>
|
objectFormState.loading ||
|
||||||
</Flex>
|
objectFormState.editDisabled
|
||||||
|
}
|
||||||
<ScrollBox>
|
loading={objectFormState.editLoading}
|
||||||
<Flex vertical gap={'large'}>
|
/>
|
||||||
<ActionHandler
|
</Space>
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Stock Audit Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={stockAuditId}
|
|
||||||
type='stockAudit'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
setCurrentObject={true}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => {
|
|
||||||
return (
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
indicator={<LoadingOutlined />}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='stockAudit'
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
content: false,
|
|
||||||
testObject: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</ObjectForm>
|
|
||||||
</InfoCollapse>
|
|
||||||
</ActionHandler>
|
|
||||||
|
|
||||||
<InfoCollapse
|
|
||||||
title='Notes'
|
|
||||||
icon={<NoteIcon />}
|
|
||||||
active={collapseState.notes}
|
|
||||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
|
||||||
collapseKey='notes'
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={objectFormState.loading}
|
|
||||||
indicator={<LoadingOutlined />}
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<NotesPanel _id={stockAuditId} type='stockAudit' />
|
|
||||||
</Card>
|
|
||||||
</Spin>
|
|
||||||
</InfoCollapse>
|
|
||||||
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('auditLogs', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{
|
|
||||||
parent:
|
|
||||||
getModelByName('stockAudit').prefix +
|
|
||||||
':' +
|
|
||||||
stockAuditId
|
|
||||||
}}
|
|
||||||
visibleColumns={{ _id: false, parent: false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
|
||||||
|
<ScrollBox>
|
||||||
|
<Flex vertical gap={'large'}>
|
||||||
|
<ActionHandler
|
||||||
|
actions={actions}
|
||||||
|
loading={objectFormState.loading}
|
||||||
|
ref={actionHandlerRef}
|
||||||
|
>
|
||||||
|
<ObjectForm
|
||||||
|
id={stockAuditId}
|
||||||
|
type='stockAudit'
|
||||||
|
style={{ height: '100%' }}
|
||||||
|
ref={objectFormRef}
|
||||||
|
setCurrentObject={true}
|
||||||
|
onStateChange={(state) => {
|
||||||
|
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ loading, isEditing, objectData }) => (
|
||||||
|
<Flex vertical gap={'large'}>
|
||||||
|
<InfoCollapse
|
||||||
|
title='Stock Audit Information'
|
||||||
|
icon={<InfoCircleIcon />}
|
||||||
|
active={collapseState.info}
|
||||||
|
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||||
|
collapseKey='info'
|
||||||
|
>
|
||||||
|
<ObjectInfo
|
||||||
|
loading={loading}
|
||||||
|
indicator={<LoadingOutlined />}
|
||||||
|
isEditing={isEditing}
|
||||||
|
type='stockAudit'
|
||||||
|
objectData={objectData}
|
||||||
|
visibleProperties={{
|
||||||
|
auditLines: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</InfoCollapse>
|
||||||
|
<InfoCollapse
|
||||||
|
title='Audit Lines'
|
||||||
|
icon={<StockAuditIcon />}
|
||||||
|
active={collapseState.auditLines}
|
||||||
|
onToggle={(expanded) =>
|
||||||
|
updateCollapseState('auditLines', expanded)
|
||||||
|
}
|
||||||
|
collapseKey='auditLines'
|
||||||
|
>
|
||||||
|
<ObjectProperty
|
||||||
|
{...getModelProperty('stockAudit', 'auditLines')}
|
||||||
|
isEditing={isEditing}
|
||||||
|
objectData={objectData}
|
||||||
|
loading={loading}
|
||||||
|
/>
|
||||||
|
</InfoCollapse>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</ObjectForm>
|
||||||
|
</ActionHandler>
|
||||||
|
|
||||||
|
<InfoCollapse
|
||||||
|
title='Notes'
|
||||||
|
icon={<NoteIcon />}
|
||||||
|
active={collapseState.notes}
|
||||||
|
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
||||||
|
collapseKey='notes'
|
||||||
|
>
|
||||||
|
<Spin
|
||||||
|
spinning={objectFormState.loading}
|
||||||
|
indicator={<LoadingOutlined />}
|
||||||
|
>
|
||||||
|
<Card>
|
||||||
|
<NotesPanel _id={stockAuditId} type='stockAudit' />
|
||||||
|
</Card>
|
||||||
|
</Spin>
|
||||||
|
</InfoCollapse>
|
||||||
|
|
||||||
|
<InfoCollapse
|
||||||
|
title='Audit Logs'
|
||||||
|
icon={<AuditLogIcon />}
|
||||||
|
active={collapseState.auditLogs}
|
||||||
|
onToggle={(expanded) =>
|
||||||
|
updateCollapseState('auditLogs', expanded)
|
||||||
|
}
|
||||||
|
collapseKey='auditLogs'
|
||||||
|
>
|
||||||
|
{objectFormState.loading ? (
|
||||||
|
<InfoCollapsePlaceholder />
|
||||||
|
) : (
|
||||||
|
<ObjectTable
|
||||||
|
type='auditLog'
|
||||||
|
masterFilter={{
|
||||||
|
parent:
|
||||||
|
getModelByName('stockAudit').prefix +
|
||||||
|
':' +
|
||||||
|
stockAuditId
|
||||||
|
}}
|
||||||
|
visibleColumns={{ _id: false, parent: false }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</InfoCollapse>
|
||||||
|
</Flex>
|
||||||
|
</ScrollBox>
|
||||||
|
</Flex>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
83
src/components/Dashboard/Management/StockAuditLevels.jsx
Normal file
83
src/components/Dashboard/Management/StockAuditLevels.jsx
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { useRef } from 'react'
|
||||||
|
import { Flex, Space } from 'antd'
|
||||||
|
import ObjectTable from '../common/ObjectTable'
|
||||||
|
import ObjectActions from '../common/ObjectActions'
|
||||||
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
|
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
||||||
|
import FilterSidebarButton from '../common/FilterSidebarButton'
|
||||||
|
import SortSidebarButton from '../common/SortSidebarButton'
|
||||||
|
import useViewMode from '../hooks/useViewMode'
|
||||||
|
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
||||||
|
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
|
||||||
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
|
import ExportListButton from '../common/ExportListButton'
|
||||||
|
|
||||||
|
const StockAuditLevels = () => {
|
||||||
|
const tableRef = useRef()
|
||||||
|
|
||||||
|
const [viewMode, setViewMode] = useViewMode('stockAuditLevel')
|
||||||
|
|
||||||
|
const [columnVisibility, setColumnVisibility] =
|
||||||
|
useColumnVisibility('stockAuditLevel')
|
||||||
|
|
||||||
|
const [showFilterSidebar, setShowFilterSidebar] =
|
||||||
|
useFilterSidebarVisibility('StockAuditLevels')
|
||||||
|
|
||||||
|
const [showSortSidebar, setShowSortSidebar] =
|
||||||
|
useSortSidebarVisibility('StockAuditLevels')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex vertical={'true'} gap='large' className='h-100'>
|
||||||
|
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
|
||||||
|
<Space size='small'>
|
||||||
|
<ObjectActions
|
||||||
|
type='stockAuditLevel'
|
||||||
|
pageName='list'
|
||||||
|
onReload={() => tableRef.current?.reload()}
|
||||||
|
/>
|
||||||
|
<ColumnViewButton
|
||||||
|
type='stockAuditLevel'
|
||||||
|
loading={false}
|
||||||
|
visibleState={columnVisibility}
|
||||||
|
updateVisibleState={setColumnVisibility}
|
||||||
|
/>
|
||||||
|
<ExportListButton objectType='stockAuditLevel' />
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<SortSidebarButton
|
||||||
|
active={showSortSidebar}
|
||||||
|
onClick={() => setShowSortSidebar(!showSortSidebar)}
|
||||||
|
/>
|
||||||
|
<FilterSidebarButton
|
||||||
|
active={showFilterSidebar}
|
||||||
|
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
||||||
|
/>
|
||||||
|
<ObjectTableViewButton
|
||||||
|
viewMode={viewMode}
|
||||||
|
setViewMode={setViewMode}
|
||||||
|
showEndingDivider={true}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</Flex>
|
||||||
|
<ObjectTable
|
||||||
|
ref={tableRef}
|
||||||
|
visibleColumns={columnVisibility}
|
||||||
|
type='stockAuditLevel'
|
||||||
|
cards={viewMode === 'cards'}
|
||||||
|
showFilterSidebar={showFilterSidebar}
|
||||||
|
showSortSidebar={showSortSidebar}
|
||||||
|
expandHeight={true}
|
||||||
|
saveFilterInSession={true}
|
||||||
|
saveFilterInUrl={true}
|
||||||
|
useFilterInSession={true}
|
||||||
|
useFilterInUrl={true}
|
||||||
|
saveSortInSession={true}
|
||||||
|
saveSortInUrl={true}
|
||||||
|
useSortInSession={true}
|
||||||
|
useSortInUrl={true}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StockAuditLevels
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import ObjectInfo from '../../common/ObjectInfo'
|
||||||
|
import NewObjectForm from '../../common/NewObjectForm'
|
||||||
|
import WizardView from '../../common/WizardView'
|
||||||
|
|
||||||
|
const NewStockAuditLevel = ({ onOk, reset, defaultValues }) => {
|
||||||
|
return (
|
||||||
|
<NewObjectForm
|
||||||
|
type='stockAuditLevel'
|
||||||
|
reset={reset}
|
||||||
|
defaultValues={{ auditLines: [], ...defaultValues }}
|
||||||
|
>
|
||||||
|
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
||||||
|
const steps = [
|
||||||
|
{
|
||||||
|
title: 'Required',
|
||||||
|
key: 'required',
|
||||||
|
content: (
|
||||||
|
<ObjectInfo
|
||||||
|
type='stockAuditLevel'
|
||||||
|
column={1}
|
||||||
|
bordered={false}
|
||||||
|
isEditing={true}
|
||||||
|
required={true}
|
||||||
|
objectData={objectData}
|
||||||
|
visibleProperties={{ auditLines: false }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Summary',
|
||||||
|
key: 'summary',
|
||||||
|
content: (
|
||||||
|
<ObjectInfo
|
||||||
|
type='stockAuditLevel'
|
||||||
|
column={1}
|
||||||
|
bordered={false}
|
||||||
|
visibleProperties={{
|
||||||
|
_id: false,
|
||||||
|
_reference: false,
|
||||||
|
createdAt: false,
|
||||||
|
updatedAt: false
|
||||||
|
}}
|
||||||
|
isEditing={false}
|
||||||
|
objectData={objectData}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
return (
|
||||||
|
<WizardView
|
||||||
|
steps={steps}
|
||||||
|
loading={submitLoading}
|
||||||
|
formValid={formValid}
|
||||||
|
title='New Stock Audit Level'
|
||||||
|
onSubmit={async () => {
|
||||||
|
const result = await handleSubmit()
|
||||||
|
if (result) {
|
||||||
|
onOk()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</NewObjectForm>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
NewStockAuditLevel.propTypes = {
|
||||||
|
onOk: PropTypes.func.isRequired,
|
||||||
|
reset: PropTypes.bool,
|
||||||
|
defaultValues: PropTypes.object
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewStockAuditLevel
|
||||||
@ -0,0 +1,231 @@
|
|||||||
|
import { useRef, useState, useMemo } from 'react'
|
||||||
|
import { useLocation } from 'react-router-dom'
|
||||||
|
import { Flex, Space } from 'antd'
|
||||||
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
|
import useCollapseState from '../../hooks/useCollapseState'
|
||||||
|
import InfoCollapse from '../../common/InfoCollapse'
|
||||||
|
import ObjectInfo from '../../common/ObjectInfo'
|
||||||
|
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
||||||
|
import ViewButton from '../../common/ViewButton'
|
||||||
|
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
||||||
|
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
||||||
|
import StockAuditLevelIcon from '../../../Icons/StockAuditLevelIcon.jsx'
|
||||||
|
import ObjectForm from '../../common/ObjectForm'
|
||||||
|
import EditButtons from '../../common/EditButtons'
|
||||||
|
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
|
||||||
|
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
|
||||||
|
import ActionHandler from '../../common/ActionHandler.jsx'
|
||||||
|
import ObjectActions from '../../common/ObjectActions.jsx'
|
||||||
|
import { useDashboardObjectTools } from '../../context/DashboardObjectToolsContext'
|
||||||
|
import ObjectTable from '../../common/ObjectTable.jsx'
|
||||||
|
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
||||||
|
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
||||||
|
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
||||||
|
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
|
||||||
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
|
|
||||||
|
const StockAuditLevelInfo = () => {
|
||||||
|
const location = useLocation()
|
||||||
|
const objectFormRef = useRef(null)
|
||||||
|
const actionHandlerRef = useRef(null)
|
||||||
|
const stockAuditLevelId = new URLSearchParams(location.search).get(
|
||||||
|
'stockAuditLevelId'
|
||||||
|
)
|
||||||
|
const [collapseState, updateCollapseState] = useCollapseState(
|
||||||
|
'StockAuditLevelInfo',
|
||||||
|
{
|
||||||
|
info: true,
|
||||||
|
auditLines: true,
|
||||||
|
auditLogs: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const [objectFormState, setEditFormState] = useState({
|
||||||
|
isEditing: false,
|
||||||
|
editLoading: false,
|
||||||
|
formValid: false,
|
||||||
|
loading: false,
|
||||||
|
editDisabled: false,
|
||||||
|
objectData: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentObjectTools = useMemo(
|
||||||
|
() => (
|
||||||
|
<ObjectTableNavigationButtons
|
||||||
|
disabled={objectFormState.loading || objectFormState.isEditing}
|
||||||
|
_id={stockAuditLevelId}
|
||||||
|
objectType='stockAuditLevel'
|
||||||
|
showEndingDivider={false}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
[objectFormState.loading, objectFormState.isEditing, stockAuditLevelId]
|
||||||
|
)
|
||||||
|
useDashboardObjectTools(currentObjectTools)
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
edit: () => {
|
||||||
|
objectFormRef?.current?.startEditing?.()
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
cancelEdit: () => {
|
||||||
|
objectFormRef?.current?.cancelEditing?.()
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
finishEdit: () => {
|
||||||
|
objectFormRef?.current?.handleUpdate?.()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
gap='large'
|
||||||
|
vertical='true'
|
||||||
|
style={{ maxHeight: '100%', minHeight: 0 }}
|
||||||
|
>
|
||||||
|
<Flex justify={'space-between'}>
|
||||||
|
<Space size='small'>
|
||||||
|
<Space size='small'>
|
||||||
|
<ObjectActions
|
||||||
|
type='stockAuditLevel'
|
||||||
|
pageName='info'
|
||||||
|
id={stockAuditLevelId}
|
||||||
|
disabled={objectFormState.loading}
|
||||||
|
objectData={objectFormState.objectData}
|
||||||
|
/>
|
||||||
|
<ViewButton
|
||||||
|
disabled={objectFormState.loading}
|
||||||
|
items={[
|
||||||
|
{ key: 'info', label: 'Stock Audit Level Information' },
|
||||||
|
{ key: 'auditLines', label: 'Audit Lines' },
|
||||||
|
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||||
|
]}
|
||||||
|
visibleState={collapseState}
|
||||||
|
updateVisibleState={updateCollapseState}
|
||||||
|
/>
|
||||||
|
<UserNotifierToggle
|
||||||
|
type='stockAuditLevel'
|
||||||
|
objectData={objectFormState.objectData}
|
||||||
|
disabled={objectFormState.loading}
|
||||||
|
/>
|
||||||
|
<DocumentPrintButton
|
||||||
|
type='stockAuditLevel'
|
||||||
|
objectData={objectFormState.objectData}
|
||||||
|
disabled={objectFormState.loading}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
<ActivityIndicator
|
||||||
|
activities={objectFormState.activities}
|
||||||
|
showStartingDivider={true}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<EditButtons
|
||||||
|
isEditing={objectFormState.isEditing}
|
||||||
|
handleUpdate={() => {
|
||||||
|
actionHandlerRef.current.callAction('finishEdit')
|
||||||
|
}}
|
||||||
|
cancelEditing={() => {
|
||||||
|
actionHandlerRef.current.callAction('cancelEdit')
|
||||||
|
}}
|
||||||
|
startEditing={() => {
|
||||||
|
actionHandlerRef.current.callAction('edit')
|
||||||
|
}}
|
||||||
|
editLoading={objectFormState.editLoading}
|
||||||
|
formValid={objectFormState.formValid}
|
||||||
|
disabled={
|
||||||
|
objectFormState.beingEditedByOther ||
|
||||||
|
objectFormState.loading ||
|
||||||
|
objectFormState.editDisabled
|
||||||
|
}
|
||||||
|
loading={objectFormState.editLoading}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</Flex>
|
||||||
|
<ScrollBox>
|
||||||
|
<Flex vertical gap={'large'}>
|
||||||
|
<ActionHandler
|
||||||
|
actions={actions}
|
||||||
|
loading={objectFormState.loading}
|
||||||
|
ref={actionHandlerRef}
|
||||||
|
>
|
||||||
|
<ObjectForm
|
||||||
|
id={stockAuditLevelId}
|
||||||
|
type='stockAuditLevel'
|
||||||
|
style={{ height: '100%' }}
|
||||||
|
ref={objectFormRef}
|
||||||
|
setCurrentObject={true}
|
||||||
|
onStateChange={(state) => {
|
||||||
|
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ loading, isEditing, objectData }) => (
|
||||||
|
<Flex vertical gap={'large'}>
|
||||||
|
<InfoCollapse
|
||||||
|
title='Stock Audit Level Information'
|
||||||
|
icon={<InfoCircleIcon />}
|
||||||
|
active={collapseState.info}
|
||||||
|
onToggle={(expanded) =>
|
||||||
|
updateCollapseState('info', expanded)
|
||||||
|
}
|
||||||
|
collapseKey='info'
|
||||||
|
>
|
||||||
|
<ObjectInfo
|
||||||
|
loading={loading}
|
||||||
|
indicator={<LoadingOutlined />}
|
||||||
|
isEditing={isEditing}
|
||||||
|
type='stockAuditLevel'
|
||||||
|
objectData={objectData}
|
||||||
|
visibleProperties={{ auditLines: false }}
|
||||||
|
/>
|
||||||
|
</InfoCollapse>
|
||||||
|
<InfoCollapse
|
||||||
|
title='Audit Lines'
|
||||||
|
icon={<StockAuditLevelIcon />}
|
||||||
|
active={collapseState.auditLines}
|
||||||
|
onToggle={(expanded) =>
|
||||||
|
updateCollapseState('auditLines', expanded)
|
||||||
|
}
|
||||||
|
collapseKey='auditLines'
|
||||||
|
>
|
||||||
|
<ObjectProperty
|
||||||
|
{...getModelProperty('stockAuditLevel', 'auditLines')}
|
||||||
|
isEditing={isEditing}
|
||||||
|
objectData={objectData}
|
||||||
|
loading={loading}
|
||||||
|
/>
|
||||||
|
</InfoCollapse>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</ObjectForm>
|
||||||
|
</ActionHandler>
|
||||||
|
<InfoCollapse
|
||||||
|
title='Audit Logs'
|
||||||
|
icon={<AuditLogIcon />}
|
||||||
|
active={collapseState.auditLogs}
|
||||||
|
onToggle={(expanded) =>
|
||||||
|
updateCollapseState('auditLogs', expanded)
|
||||||
|
}
|
||||||
|
collapseKey='auditLogs'
|
||||||
|
>
|
||||||
|
{objectFormState.loading ? (
|
||||||
|
<InfoCollapsePlaceholder />
|
||||||
|
) : (
|
||||||
|
<ObjectTable
|
||||||
|
type='auditLog'
|
||||||
|
masterFilter={{
|
||||||
|
parent:
|
||||||
|
getModelByName('stockAuditLevel').prefix +
|
||||||
|
':' +
|
||||||
|
stockAuditLevelId
|
||||||
|
}}
|
||||||
|
visibleColumns={{ _id: false, parent: false }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</InfoCollapse>
|
||||||
|
</Flex>
|
||||||
|
</ScrollBox>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StockAuditLevelInfo
|
||||||
@ -11,6 +11,7 @@ import PartStockIcon from './PartStockIcon'
|
|||||||
import ProductStockIcon from './ProductStockIcon'
|
import ProductStockIcon from './ProductStockIcon'
|
||||||
import StockEventIcon from './StockEventIcon'
|
import StockEventIcon from './StockEventIcon'
|
||||||
import StockAuditIcon from './StockAuditIcon'
|
import StockAuditIcon from './StockAuditIcon'
|
||||||
|
import StockAuditLevelIcon from './StockAuditLevelIcon'
|
||||||
import PurchaseOrderIcon from './PurchaseOrderIcon'
|
import PurchaseOrderIcon from './PurchaseOrderIcon'
|
||||||
import ShipmentIcon from './ShipmentIcon'
|
import ShipmentIcon from './ShipmentIcon'
|
||||||
import OrderItemIcon from './OrderItemIcon'
|
import OrderItemIcon from './OrderItemIcon'
|
||||||
@ -74,6 +75,7 @@ const sidebarIconMap = {
|
|||||||
productStock: <ProductStockIcon />,
|
productStock: <ProductStockIcon />,
|
||||||
stockEvent: <StockEventIcon />,
|
stockEvent: <StockEventIcon />,
|
||||||
stockAudit: <StockAuditIcon />,
|
stockAudit: <StockAuditIcon />,
|
||||||
|
stockAuditLevel: <StockAuditLevelIcon />,
|
||||||
purchaseOrder: <PurchaseOrderIcon />,
|
purchaseOrder: <PurchaseOrderIcon />,
|
||||||
orderItem: <OrderItemIcon />,
|
orderItem: <OrderItemIcon />,
|
||||||
shipment: <ShipmentIcon />,
|
shipment: <ShipmentIcon />,
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import { Initial } from './models/Initial'
|
|||||||
import { FilamentStock } from './models/FilamentStock'
|
import { FilamentStock } from './models/FilamentStock'
|
||||||
import { StockEvent } from './models/StockEvent'
|
import { StockEvent } from './models/StockEvent'
|
||||||
import { StockAudit } from './models/StockAudit'
|
import { StockAudit } from './models/StockAudit'
|
||||||
|
import { StockAuditLevel } from './models/StockAuditLevel'
|
||||||
import { PartStock } from './models/PartStock'
|
import { PartStock } from './models/PartStock'
|
||||||
import { ProductStock } from './models/ProductStock'
|
import { ProductStock } from './models/ProductStock'
|
||||||
import { StockLocation } from './models/StockLocation'
|
import { StockLocation } from './models/StockLocation'
|
||||||
@ -79,6 +80,7 @@ export const objectModels = [
|
|||||||
FilamentStock,
|
FilamentStock,
|
||||||
StockEvent,
|
StockEvent,
|
||||||
StockAudit,
|
StockAudit,
|
||||||
|
StockAuditLevel,
|
||||||
PartStock,
|
PartStock,
|
||||||
ProductStock,
|
ProductStock,
|
||||||
StockLocation,
|
StockLocation,
|
||||||
@ -137,6 +139,7 @@ export {
|
|||||||
FilamentStock,
|
FilamentStock,
|
||||||
StockEvent,
|
StockEvent,
|
||||||
StockAudit,
|
StockAudit,
|
||||||
|
StockAuditLevel,
|
||||||
PartStock,
|
PartStock,
|
||||||
ProductStock,
|
ProductStock,
|
||||||
StockLocation,
|
StockLocation,
|
||||||
|
|||||||
@ -1,17 +1,26 @@
|
|||||||
import { createElement, lazy } from 'react'
|
import { createElement, lazy } from 'react'
|
||||||
|
|
||||||
const StockAuditInfo = lazy(
|
const StockAuditInfo = lazy(
|
||||||
() => import('../../components/Dashboard/Inventory/StockAudits/StockAuditInfo')
|
() =>
|
||||||
|
import('../../components/Dashboard/Inventory/StockAudits/StockAuditInfo')
|
||||||
)
|
)
|
||||||
const NewStockAudit = lazy(
|
const NewStockAudit = lazy(
|
||||||
() => import('../../components/Dashboard/Inventory/StockAudits/NewStockAudit')
|
() => import('../../components/Dashboard/Inventory/StockAudits/NewStockAudit')
|
||||||
)
|
)
|
||||||
|
const DeleteObject = lazy(
|
||||||
|
() => import('../../components/Dashboard/common/DeleteObject')
|
||||||
|
)
|
||||||
|
const PostStockAudit = lazy(
|
||||||
|
() =>
|
||||||
|
import('../../components/Dashboard/Inventory/StockAudits/PostStockAudit')
|
||||||
|
)
|
||||||
import StockAuditIcon from '../../components/Icons/StockAuditIcon'
|
import StockAuditIcon from '../../components/Icons/StockAuditIcon'
|
||||||
import PlusIcon from '../../components/Icons/PlusIcon'
|
import PlusIcon from '../../components/Icons/PlusIcon'
|
||||||
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
|
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
|
||||||
import EditIcon from '../../components/Icons/EditIcon'
|
import EditIcon from '../../components/Icons/EditIcon'
|
||||||
import CheckIcon from '../../components/Icons/CheckIcon'
|
import CheckIcon from '../../components/Icons/CheckIcon'
|
||||||
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
||||||
|
import BinIcon from '../../components/Icons/BinIcon'
|
||||||
import ListIcon from '../../components/Icons/ListIcon'
|
import ListIcon from '../../components/Icons/ListIcon'
|
||||||
|
|
||||||
export const StockAudit = {
|
export const StockAudit = {
|
||||||
@ -30,7 +39,11 @@ export const StockAudit = {
|
|||||||
label: 'New Stock Audit',
|
label: 'New Stock Audit',
|
||||||
icon: PlusIcon,
|
icon: PlusIcon,
|
||||||
content: (objectData, { onOk } = {}) => {
|
content: (objectData, { onOk } = {}) => {
|
||||||
return createElement(NewStockAudit, { defaultValues: objectData, onOk, reset: true })
|
return createElement(NewStockAudit, {
|
||||||
|
defaultValues: objectData,
|
||||||
|
onOk,
|
||||||
|
reset: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -58,6 +71,9 @@ export const StockAudit = {
|
|||||||
icon: EditIcon,
|
icon: EditIcon,
|
||||||
visible: (objectData) => {
|
visible: (objectData) => {
|
||||||
return !(objectData?._isEditing && objectData?._isEditing == true)
|
return !(objectData?._isEditing && objectData?._isEditing == true)
|
||||||
|
},
|
||||||
|
disabled: (objectData) => {
|
||||||
|
return objectData?.state?.type != 'draft'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -80,6 +96,40 @@ export const StockAudit = {
|
|||||||
return objectData?._isEditing && objectData?._isEditing == true
|
return objectData?._isEditing && objectData?._isEditing == true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{ type: 'divider' },
|
||||||
|
{
|
||||||
|
name: 'delete',
|
||||||
|
type: 'modal',
|
||||||
|
modalWidth: 520,
|
||||||
|
modalCentered: true,
|
||||||
|
label: 'Delete',
|
||||||
|
icon: BinIcon,
|
||||||
|
danger: true,
|
||||||
|
visible: (objectData) => {
|
||||||
|
return !(objectData?._isEditing && objectData?._isEditing == true)
|
||||||
|
},
|
||||||
|
disabled: (objectData) => {
|
||||||
|
return objectData?.state?.type != 'draft'
|
||||||
|
},
|
||||||
|
content: (objectData, { onOk } = {}) => {
|
||||||
|
return createElement(DeleteObject, { objectData, onOk })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ type: 'divider' },
|
||||||
|
{
|
||||||
|
name: 'post',
|
||||||
|
type: 'modal',
|
||||||
|
modalWidth: 520,
|
||||||
|
modalCentered: true,
|
||||||
|
label: 'Post',
|
||||||
|
icon: CheckIcon,
|
||||||
|
visible: (objectData) => {
|
||||||
|
return objectData?.state?.type == 'draft'
|
||||||
|
},
|
||||||
|
content: (objectData, { onOk } = {}) => {
|
||||||
|
return createElement(PostStockAudit, { objectData, onOk })
|
||||||
|
}
|
||||||
|
}
|
||||||
],
|
],
|
||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
@ -87,17 +137,26 @@ export const StockAudit = {
|
|||||||
content: () => createElement(StockAuditInfo)
|
content: () => createElement(StockAuditInfo)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
columns: ['_reference', 'state', 'createdAt', 'updatedAt'],
|
columns: [
|
||||||
filters: [
|
'_reference',
|
||||||
'status',
|
|
||||||
'type',
|
|
||||||
'createdBy',
|
|
||||||
'state',
|
'state',
|
||||||
|
'auditLevel',
|
||||||
|
'stockLocation',
|
||||||
|
'postedAt',
|
||||||
|
'createdAt',
|
||||||
|
'updatedAt'
|
||||||
|
],
|
||||||
|
filters: [
|
||||||
|
'state',
|
||||||
|
'state.type',
|
||||||
|
'auditLevel',
|
||||||
|
'stockLocation',
|
||||||
|
'postedAt',
|
||||||
'createdAt',
|
'createdAt',
|
||||||
'updatedAt',
|
'updatedAt',
|
||||||
'_reference'
|
'_reference'
|
||||||
],
|
],
|
||||||
sorters: ['createdAt','updatedAt','state'],
|
sorters: ['createdAt', 'updatedAt', 'postedAt', 'state'],
|
||||||
group: ['state'],
|
group: ['state'],
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
@ -126,6 +185,13 @@ export const StockAudit = {
|
|||||||
readOnly: true,
|
readOnly: true,
|
||||||
columnWidth: 180
|
columnWidth: 180
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
label: 'Updated At',
|
||||||
|
type: 'dateTime',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 175
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
label: 'State',
|
label: 'State',
|
||||||
@ -134,11 +200,130 @@ export const StockAudit = {
|
|||||||
columnWidth: 260
|
columnWidth: 260
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'updatedAt',
|
name: 'postedAt',
|
||||||
label: 'Updated At',
|
label: 'Posted At',
|
||||||
type: 'dateTime',
|
type: 'dateTime',
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
columnWidth: 175
|
columnWidth: 175
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'auditLevel',
|
||||||
|
label: 'Audit Level',
|
||||||
|
type: 'object',
|
||||||
|
objectType: 'stockAuditLevel',
|
||||||
|
showHyperlink: true,
|
||||||
|
required: true,
|
||||||
|
columnWidth: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'stockLocation',
|
||||||
|
label: 'Stock Location',
|
||||||
|
type: 'object',
|
||||||
|
objectType: 'stockLocation',
|
||||||
|
showHyperlink: true,
|
||||||
|
required: true,
|
||||||
|
columnWidth: 220
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'auditLines',
|
||||||
|
label: 'Audit Lines',
|
||||||
|
type: 'objectChildren',
|
||||||
|
required: false,
|
||||||
|
size: 'medium',
|
||||||
|
canAddRemove: false,
|
||||||
|
columns: [
|
||||||
|
'itemType',
|
||||||
|
'item',
|
||||||
|
'itemSku',
|
||||||
|
'current',
|
||||||
|
'actual',
|
||||||
|
'new',
|
||||||
|
'variance'
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
name: 'itemType',
|
||||||
|
label: 'Item Type',
|
||||||
|
type: 'objectType',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'item',
|
||||||
|
label: 'Item',
|
||||||
|
type: 'object',
|
||||||
|
objectType: (row) => row?.itemType,
|
||||||
|
readOnly: true,
|
||||||
|
showHyperlink: true,
|
||||||
|
columnWidth: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'itemSku',
|
||||||
|
label: 'Item SKU',
|
||||||
|
type: 'object',
|
||||||
|
objectType: (row) => {
|
||||||
|
if (row?.itemType === 'filament') return 'filamentSku'
|
||||||
|
if (row?.itemType === 'part') return 'partSku'
|
||||||
|
if (row?.itemType === 'product') return 'productSku'
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
readOnly: true,
|
||||||
|
showHyperlink: true,
|
||||||
|
columnWidth: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'current',
|
||||||
|
label: 'Current',
|
||||||
|
type: 'number',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 150,
|
||||||
|
suffix: (row) => (row?.itemType === 'filament' ? 'g net' : null)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'actual',
|
||||||
|
label: 'Actual',
|
||||||
|
type: 'number',
|
||||||
|
columnWidth: 150,
|
||||||
|
suffix: (row) => (row?.itemType === 'filament' ? 'g net' : null)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'new',
|
||||||
|
label: 'New',
|
||||||
|
type: 'number',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 150,
|
||||||
|
suffix: (row) => (row?.itemType === 'filament' ? 'g net' : null),
|
||||||
|
value: (row) => Number(row?.actual) || 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'variance',
|
||||||
|
label: 'Variance',
|
||||||
|
type: 'variance',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 150,
|
||||||
|
suffix: (row) => (row?.itemType === 'filament' ? 'g net' : null),
|
||||||
|
value: (row) => {
|
||||||
|
const current = Number(row?.current) || 0
|
||||||
|
const actual = Number(row?.actual) || 0
|
||||||
|
return actual - current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stats: [
|
||||||
|
{
|
||||||
|
name: 'draft.count',
|
||||||
|
label: 'Draft',
|
||||||
|
type: 'number',
|
||||||
|
color: 'default'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'complete.count',
|
||||||
|
label: 'Complete',
|
||||||
|
type: 'number',
|
||||||
|
color: 'success'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
239
src/database/models/StockAuditLevel.js
Normal file
239
src/database/models/StockAuditLevel.js
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
import { createElement, lazy } from 'react'
|
||||||
|
|
||||||
|
const StockAuditLevelInfo = lazy(
|
||||||
|
() =>
|
||||||
|
import('../../components/Dashboard/Management/StockAuditLevels/StockAuditLevelInfo')
|
||||||
|
)
|
||||||
|
const NewStockAuditLevel = lazy(
|
||||||
|
() =>
|
||||||
|
import('../../components/Dashboard/Management/StockAuditLevels/NewStockAuditLevel')
|
||||||
|
)
|
||||||
|
const DeleteObject = lazy(
|
||||||
|
() => import('../../components/Dashboard/common/DeleteObject')
|
||||||
|
)
|
||||||
|
import StockAuditLevelIcon from '../../components/Icons/StockAuditLevelIcon'
|
||||||
|
import PlusIcon from '../../components/Icons/PlusIcon'
|
||||||
|
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
|
||||||
|
import EditIcon from '../../components/Icons/EditIcon'
|
||||||
|
import CheckIcon from '../../components/Icons/CheckIcon'
|
||||||
|
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
||||||
|
import BinIcon from '../../components/Icons/BinIcon'
|
||||||
|
import ListIcon from '../../components/Icons/ListIcon'
|
||||||
|
|
||||||
|
export const StockAuditLevel = {
|
||||||
|
name: 'stockAuditLevel',
|
||||||
|
label: 'Stock Audit Level',
|
||||||
|
labelPlural: 'Stock Audit Levels',
|
||||||
|
url: '/dashboard/management/stockauditlevels',
|
||||||
|
prefix: 'SAL',
|
||||||
|
icon: StockAuditLevelIcon,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
name: 'new',
|
||||||
|
type: 'modal',
|
||||||
|
pageName: 'list',
|
||||||
|
modalWidth: 900,
|
||||||
|
label: 'New Stock Audit Level',
|
||||||
|
icon: PlusIcon,
|
||||||
|
content: (objectData, { onOk } = {}) => {
|
||||||
|
return createElement(NewStockAuditLevel, {
|
||||||
|
defaultValues: objectData,
|
||||||
|
onOk,
|
||||||
|
reset: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'list',
|
||||||
|
type: 'page',
|
||||||
|
pageName: 'list',
|
||||||
|
label: 'List',
|
||||||
|
icon: ListIcon
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'info',
|
||||||
|
type: 'page',
|
||||||
|
pageName: 'info',
|
||||||
|
label: 'Info',
|
||||||
|
default: true,
|
||||||
|
row: true,
|
||||||
|
icon: InfoCircleIcon
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'edit',
|
||||||
|
type: 'page',
|
||||||
|
pageName: 'info',
|
||||||
|
label: 'Edit',
|
||||||
|
row: true,
|
||||||
|
icon: EditIcon,
|
||||||
|
visible: (objectData) => {
|
||||||
|
return !(objectData?._isEditing && objectData?._isEditing == true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cancelEdit',
|
||||||
|
label: 'Cancel Edits',
|
||||||
|
type: 'page',
|
||||||
|
pageName: 'info',
|
||||||
|
icon: XMarkIcon,
|
||||||
|
visible: (objectData) => {
|
||||||
|
return objectData?._isEditing && objectData?._isEditing == true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'finishEdit',
|
||||||
|
label: 'Save Edits',
|
||||||
|
type: 'page',
|
||||||
|
pageName: 'info',
|
||||||
|
icon: CheckIcon,
|
||||||
|
visible: (objectData) => {
|
||||||
|
return objectData?._isEditing && objectData?._isEditing == true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ type: 'divider' },
|
||||||
|
{
|
||||||
|
name: 'delete',
|
||||||
|
type: 'modal',
|
||||||
|
modalWidth: 520,
|
||||||
|
modalCentered: true,
|
||||||
|
label: 'Delete',
|
||||||
|
icon: BinIcon,
|
||||||
|
danger: true,
|
||||||
|
content: (objectData, { onOk } = {}) => {
|
||||||
|
return createElement(DeleteObject, { objectData, onOk })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
name: 'info',
|
||||||
|
content: () => createElement(StockAuditLevelInfo)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
columns: ['_reference', 'name', 'tags', 'createdAt', 'updatedAt'],
|
||||||
|
filters: ['name', 'tags', 'createdAt', 'updatedAt', '_reference'],
|
||||||
|
sorters: ['name', 'createdAt', 'updatedAt'],
|
||||||
|
group: ['tags'],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
name: '_id',
|
||||||
|
label: 'ID',
|
||||||
|
type: 'id',
|
||||||
|
objectType: 'stockAuditLevel',
|
||||||
|
showCopy: true,
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
label: 'Created At',
|
||||||
|
type: 'dateTime',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 175
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '_reference',
|
||||||
|
label: 'Reference',
|
||||||
|
type: 'reference',
|
||||||
|
columnFixed: 'left',
|
||||||
|
objectType: 'stockAuditLevel',
|
||||||
|
showCopy: true,
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
label: 'Updated At',
|
||||||
|
type: 'dateTime',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 175
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
label: 'Name',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
columnWidth: 220,
|
||||||
|
columnFixed: 'left'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tags',
|
||||||
|
label: 'Tags',
|
||||||
|
type: 'tags',
|
||||||
|
required: false,
|
||||||
|
columnWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'auditLines',
|
||||||
|
label: 'Audit Lines',
|
||||||
|
type: 'objectChildren',
|
||||||
|
required: false,
|
||||||
|
size: 'medium',
|
||||||
|
canAddRemove: true,
|
||||||
|
columns: ['itemType', 'allItems', 'item', 'allSkus', 'itemSku'],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
name: 'itemType',
|
||||||
|
label: 'Item Type',
|
||||||
|
type: 'objectType',
|
||||||
|
required: true,
|
||||||
|
columnWidth: 150,
|
||||||
|
masterFilter: ['filament', 'part', 'product']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'allItems',
|
||||||
|
label: 'All Items',
|
||||||
|
type: 'bool',
|
||||||
|
columnWidth: 110
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'item',
|
||||||
|
label: 'Item',
|
||||||
|
type: 'object',
|
||||||
|
objectType: (row) => row?.itemType,
|
||||||
|
showHyperlink: true,
|
||||||
|
columnWidth: 220,
|
||||||
|
disabled: (row) => row?.allItems === true,
|
||||||
|
value: (row) => (row?.allItems ? null : row?.item)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'allSkus',
|
||||||
|
label: 'All SKUs',
|
||||||
|
type: 'bool',
|
||||||
|
columnWidth: 110,
|
||||||
|
disabled: (row) => row?.allItems === true,
|
||||||
|
value: (row) => (row?.allItems ? true : row?.allSkus)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'itemSku',
|
||||||
|
label: 'Item SKU',
|
||||||
|
type: 'object',
|
||||||
|
objectType: (row) => {
|
||||||
|
if (row?.itemType === 'filament') return 'filamentSku'
|
||||||
|
if (row?.itemType === 'part') return 'partSku'
|
||||||
|
if (row?.itemType === 'product') return 'productSku'
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
showHyperlink: true,
|
||||||
|
columnWidth: 220,
|
||||||
|
disabled: (row) => row?.allItems === true || row?.allSkus === true,
|
||||||
|
value: (row) =>
|
||||||
|
row?.allItems || row?.allSkus ? null : row?.itemSku,
|
||||||
|
masterFilter: (row) => {
|
||||||
|
const itemId = row?.item?._id ?? row?.item
|
||||||
|
if (row?.itemType === 'filament' && itemId) {
|
||||||
|
return { filament: itemId }
|
||||||
|
}
|
||||||
|
if (row?.itemType === 'part' && itemId) {
|
||||||
|
return { part: itemId }
|
||||||
|
}
|
||||||
|
if (row?.itemType === 'product' && itemId) {
|
||||||
|
return { product: itemId }
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,13 +1,16 @@
|
|||||||
import { createElement, lazy } from 'react'
|
import { createElement, lazy } from 'react'
|
||||||
|
|
||||||
const StockTransferInfo = lazy(
|
const StockTransferInfo = lazy(
|
||||||
() => import('../../components/Dashboard/Inventory/StockTransfers/StockTransferInfo')
|
() =>
|
||||||
|
import('../../components/Dashboard/Inventory/StockTransfers/StockTransferInfo')
|
||||||
)
|
)
|
||||||
const NewStockTransfer = lazy(
|
const NewStockTransfer = lazy(
|
||||||
() => import('../../components/Dashboard/Inventory/StockTransfers/NewStockTransfer')
|
() =>
|
||||||
|
import('../../components/Dashboard/Inventory/StockTransfers/NewStockTransfer')
|
||||||
)
|
)
|
||||||
const PostStockTransfer = lazy(
|
const PostStockTransfer = lazy(
|
||||||
() => import('../../components/Dashboard/Inventory/StockTransfers/PostStockTransfer')
|
() =>
|
||||||
|
import('../../components/Dashboard/Inventory/StockTransfers/PostStockTransfer')
|
||||||
)
|
)
|
||||||
const DeleteObject = lazy(
|
const DeleteObject = lazy(
|
||||||
() => import('../../components/Dashboard/common/DeleteObject')
|
() => import('../../components/Dashboard/common/DeleteObject')
|
||||||
@ -37,7 +40,11 @@ export const StockTransfer = {
|
|||||||
label: 'New Stock Transfer',
|
label: 'New Stock Transfer',
|
||||||
icon: PlusIcon,
|
icon: PlusIcon,
|
||||||
content: (objectData, { onOk } = {}) => {
|
content: (objectData, { onOk } = {}) => {
|
||||||
return createElement(NewStockTransfer, { defaultValues: objectData, onOk, reset: true })
|
return createElement(NewStockTransfer, {
|
||||||
|
defaultValues: objectData,
|
||||||
|
onOk,
|
||||||
|
reset: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -113,6 +120,7 @@ export const StockTransfer = {
|
|||||||
name: 'post',
|
name: 'post',
|
||||||
type: 'modal',
|
type: 'modal',
|
||||||
modalWidth: 520,
|
modalWidth: 520,
|
||||||
|
modalCentered: true,
|
||||||
label: 'Post',
|
label: 'Post',
|
||||||
icon: CheckIcon,
|
icon: CheckIcon,
|
||||||
visible: (objectData) => {
|
visible: (objectData) => {
|
||||||
@ -138,13 +146,7 @@ export const StockTransfer = {
|
|||||||
'updatedAt',
|
'updatedAt',
|
||||||
'_reference'
|
'_reference'
|
||||||
],
|
],
|
||||||
sorters: [
|
sorters: ['name', 'createdAt', 'postedAt', 'state', 'updatedAt'],
|
||||||
'name',
|
|
||||||
'createdAt',
|
|
||||||
'postedAt',
|
|
||||||
'state',
|
|
||||||
'updatedAt'
|
|
||||||
],
|
|
||||||
columns: [
|
columns: [
|
||||||
'_reference',
|
'_reference',
|
||||||
'name',
|
'name',
|
||||||
@ -180,6 +182,13 @@ export const StockTransfer = {
|
|||||||
readOnly: true,
|
readOnly: true,
|
||||||
columnWidth: 180
|
columnWidth: 180
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
label: 'Updated At',
|
||||||
|
type: 'dateTime',
|
||||||
|
readOnly: true,
|
||||||
|
columnWidth: 175
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
@ -188,13 +197,6 @@ export const StockTransfer = {
|
|||||||
columnWidth: 220,
|
columnWidth: 220,
|
||||||
columnFixed: 'left'
|
columnFixed: 'left'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'state',
|
|
||||||
label: 'State',
|
|
||||||
type: 'state',
|
|
||||||
readOnly: true,
|
|
||||||
columnWidth: 260
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'postedAt',
|
name: 'postedAt',
|
||||||
label: 'Posted At',
|
label: 'Posted At',
|
||||||
@ -203,12 +205,13 @@ export const StockTransfer = {
|
|||||||
columnWidth: 175
|
columnWidth: 175
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'updatedAt',
|
name: 'state',
|
||||||
label: 'Updated At',
|
label: 'State',
|
||||||
type: 'dateTime',
|
type: 'state',
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
columnWidth: 175
|
columnWidth: 260
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'lines',
|
name: 'lines',
|
||||||
label: 'Lines',
|
label: 'Lines',
|
||||||
|
|||||||
@ -53,6 +53,12 @@ const managementSidebarItems = [
|
|||||||
label: 'Materials',
|
label: 'Materials',
|
||||||
path: '/dashboard/management/materials'
|
path: '/dashboard/management/materials'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'stockAuditLevels',
|
||||||
|
iconKey: 'stockAuditLevel',
|
||||||
|
label: 'Stock Audit Levels',
|
||||||
|
path: '/dashboard/management/stockauditlevels'
|
||||||
|
},
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
{
|
{
|
||||||
key: 'couriers',
|
key: 'couriers',
|
||||||
|
|||||||
@ -73,6 +73,9 @@ const Files = lazy(() => import('../components/Dashboard/Management/Files.jsx'))
|
|||||||
const TaxRates = lazy(
|
const TaxRates = lazy(
|
||||||
() => import('../components/Dashboard/Management/TaxRates.jsx')
|
() => import('../components/Dashboard/Management/TaxRates.jsx')
|
||||||
)
|
)
|
||||||
|
const StockAuditLevels = lazy(
|
||||||
|
() => import('../components/Dashboard/Management/StockAuditLevels.jsx')
|
||||||
|
)
|
||||||
const About = lazy(() => import('../components/Dashboard/Management/About.jsx'))
|
const About = lazy(() => import('../components/Dashboard/Management/About.jsx'))
|
||||||
|
|
||||||
const ManagementRoutes = [
|
const ManagementRoutes = [
|
||||||
@ -151,7 +154,12 @@ const ManagementRoutes = [
|
|||||||
<Route key='settings' path='management/settings' element={<Settings />} />,
|
<Route key='settings' path='management/settings' element={<Settings />} />,
|
||||||
<Route key='about' path='management/about' element={<About />} />,
|
<Route key='about' path='management/about' element={<About />} />,
|
||||||
<Route key='auditlogs' path='management/auditlogs' element={<AuditLogs />} />,
|
<Route key='auditlogs' path='management/auditlogs' element={<AuditLogs />} />,
|
||||||
<Route key='taxrates' path='management/taxrates' element={<TaxRates />} />
|
<Route key='taxrates' path='management/taxrates' element={<TaxRates />} />,
|
||||||
|
<Route
|
||||||
|
key='stockauditlevels'
|
||||||
|
path='management/stockauditlevels'
|
||||||
|
element={<StockAuditLevels />}
|
||||||
|
/>
|
||||||
]
|
]
|
||||||
|
|
||||||
export default ManagementRoutes
|
export default ManagementRoutes
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user